6

Bir ASP.NET WebApi arka ucuna oturum açma ve şifre gönderen ve bu kullanıcıya Thinktecture ile giriş yapan bir AngularJs web'i yapmaya çalışıyorum.AngularJs ThinkTecture ile ASP.NET WebApi Kimlik Doğrulaması

WS-Federation kullanarak başka bir proje olan ASP.NET MVC ile çalışarak Thinktecture çalışıyorum. Şimdi benzer bir şey yapmaya çalışıyorum ama bazı bileşenleri değiştiriyorum ve işe yaramayacağım.

ASP.NET WebApi'den UserName ve parolayı Thinktecture'a nasıl gönderebilirim ve doğrulayabilirim?

using System.Collections.Generic; 
using System.IdentityModel.Services; 
using System.Web.Http; 
using WebApi_AngularJs.Model; 

namespace WebApi_AngularJs.Controllers 
{ 
    public class AuthorizationController : ApiController 
    {  
     // POST: api/Authorization 
     public LoginResponse Post([FromBody]Login data) 
     { 
      //HOW TO SEND data.user and data.password to ThinkTecture and get 
      //response if user valid or not?? 
      var response = new LoginResponse { access_token = "token", data = "data"}; 
      return response; 
     } 

    } 
} 

Teşekkür ederiz!

cevap

5

Son olarak, bir çok okuduktan sonra ben bu var

WebAPI olarak
'use strict'; 
app.factory('authService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) { 

var serviceBase = 'http://localhost:64346/'; 
var authServiceFactory = {}; 

var _authData = localStorageService.get('authorizationData'); 

var _authentication = { 
    isAuth: _authData != null? true : false, 
    userName: _authData != null ? _authData.userName : "" 
}; 

var _saveRegistration = function (registration) { 

    _logOut(); 

    return $http.post(serviceBase + 'api/account/register', registration).then(function (response) { 
     return response; 
    }); 

}; 

var _login = function (loginData) { 

    var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password; 

    var deferred = $q.defer(); 

    $http.post(serviceBase + 'api/authorization', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) { 

     localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName }); 

     _authentication.isAuth = true; 
     _authentication.userName = loginData.userName; 

     deferred.resolve(response); 

    }).error(function (err, status) { 
     _logOut(); 
     deferred.reject(err); 
    }); 

    return deferred.promise; 

}; 

var _logOut = function() { 

    $http.delete(serviceBase + 'api/authorization').success(function() { 
     localStorageService.remove('authorizationData'); 

     _authentication.isAuth = false; 
     _authentication.userName = ""; 
    }); 
}; 

var _fillAuthData = function() { 

    var authData = localStorageService.get('authorizationData'); 
    if (authData) { 
     _authentication.isAuth = true; 
     _authentication.userName = authData.userName; 
    } 

} 

authServiceFactory.saveRegistration = _saveRegistration; 
authServiceFactory.login = _login; 
authServiceFactory.logOut = _logOut; 
authServiceFactory.fillAuthData = _fillAuthData; 
authServiceFactory.authentication = _authentication; 

return authServiceFactory; 
}]); 

: Web.config içinde

using System.Collections.Generic; 
using System.Configuration; 
using System.IdentityModel.Protocols.WSTrust; 
using System.IdentityModel.Services; 
using System.IdentityModel.Tokens; 
using System.IO; 
using System.Linq; 
using System.Net; 
using System.Security.Claims; 
using System.ServiceModel; 
using System.ServiceModel.Description; 
using System.ServiceModel.Security; 
using System.Web.Http; 
using System.Xml; 
using Thinktecture.IdentityModel.Constants; 
using Thinktecture.IdentityModel.WSTrust; 
using WebApi_AngularJs.Model; 

namespace WebApi_AngularJs.Controllers 
{ 
    public class AuthorizationController : ApiController 
    { 
     // GET: api/Authorization 
     public IEnumerable<string> Get() 
     { 
      return new string[] { "value1", "value2" }; 
     } 

     // GET: api/Authorization/5 
     [Authorize] 
     public string Get(int id) 
     { 
      return "value"; 
     } 

    // POST: api/Authorization 
    public LoginResponse Post([FromBody]Login data) 
    { 
     var credentials = new ClientCredentials(); 
     credentials.UserName.UserName = data.UserName; 
     credentials.UserName.Password = data.Password; 

     ServicePointManager.ServerCertificateValidationCallback = (obj, certificate, chain, errors) => true; 

     var claims = GetClaimsFromIdentityServer(data.UserName, data.Password); 

     var response = new LoginResponse(); 
     if (claims != null) 
     { 
      //All set so now create a SessionSecurityToken 
      var token = new SessionSecurityToken(claims) 
      { 
       IsReferenceMode = true //this is 
       //important.this is how you say create 
       //the token in reference mode meaning 
       //your session cookie will contain only a 
       //referenceid(which is very small) and 
       //all claims will be stored on the server 
      }; 
      FederatedAuthentication.WSFederationAuthenticationModule. 
      SetPrincipalAndWriteSessionToken(token, true); 

      response = new LoginResponse { access_token = token.Id , data = "data"}; 
     } 

     return response; 
    } 

    // PUT: api/Authorization/5 
    public void Put(int id, [FromBody]string value) 
    { 
    } 

    // DELETE: api/Authorization/ 
    public void Delete() 
    { 
     //clear local cookie 
     FederatedAuthentication.SessionAuthenticationModule.SignOut(); 
     FederatedAuthentication.SessionAuthenticationModule.DeleteSessionTokenCookie(); 
     FederatedAuthentication.WSFederationAuthenticationModule.SignOut(false); 
    } 

    private ClaimsPrincipal GetClaimsFromIdentityServer(string username, string password) 
    { 
     const string WS_TRUST_END_POINT = "https://srv:4443/issue/wstrust/mixed/username"; 
     var factory = new System.ServiceModel.Security.WSTrustChannelFactory 
     (new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential), 
            string.Format(WS_TRUST_END_POINT)); 
     factory.TrustVersion = TrustVersion.WSTrust13; 
     factory.Credentials.UserName.UserName = username; 
     factory.Credentials.UserName.Password = password; 

     var rst = new System.IdentityModel.Protocols.WSTrust.RequestSecurityToken 
     { 
      RequestType = RequestTypes.Issue, 
      KeyType = KeyTypes.Bearer, 
      TokenType = TokenTypes.Saml2TokenProfile11, 
      AppliesTo = new EndpointReference 
      ("urn:webapisecurity") 
     }; 
     var st = factory.CreateChannel().Issue(rst); 
     var token = st as GenericXmlSecurityToken; 
     var handlers = FederatedAuthentication.FederationConfiguration. 
     IdentityConfiguration.SecurityTokenHandlers; 
     var token = handlers.ReadToken(new XmlTextReader 
     (new StringReader(token.TokenXml.OuterXml))) as Saml2SecurityToken; 
     var identity = handlers.ValidateToken(token).First(); 
     var principal = new ClaimsPrincipal(identity); 
     return principal; 
    } 
} 
} 

:

<?xml version="1.0" encoding="utf-8"?> 
<!-- 
    For more information on how to configure your ASP.NET application, please visit 
    http://go.microsoft.com/fwlink/?LinkId=301879 
    --> 
<configuration> 
    <configSections> 
    <section name="system.identityModel" type="System.IdentityModel.Configuration.SystemIdentityModelSection, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> 
    <section name="system.identityModel.services" type="System.IdentityModel.Services.Configuration.SystemIdentityModelServicesSection, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089" /> 
    <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --> 
    <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> 
    </configSections> 
    <appSettings> 
    <add key="webpages:Version" value="3.0.0.0" /> 
    <add key="webpages:Enabled" value="false" /> 
    <add key="ClientValidationEnabled" value="true" /> 
    <add key="UnobtrusiveJavaScriptEnabled" value="true" /> 
    <add key="ida:FederationMetadataLocation" value="https://srv:4443/FederationMetadata/2007-06/FederationMetadata.xml" /> 
    <add key="ida:Realm" value="urn:webapisecurity" /> 
    <add key="ida:AudienceUri" value="urn:webapisecurity" /> 
    <add key="AppName" value="Web API Security Sample" /> 
    </appSettings> 
    <system.web> 
    <compilation debug="true" targetFramework="4.5" /> 
    <httpRuntime targetFramework="4.5" /> 
    </system.web> 
    <system.webServer> 
    <handlers> 
     <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> 
     <remove name="OPTIONSVerbHandler" /> 
     <remove name="TRACEVerbHandler" /> 
     <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> 
    </handlers> 
    <modules> 
     <add name="WSFederationAuthenticationModule" type="System.IdentityModel.Services.WSFederationAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" /> 
     <add name="SessionAuthenticationModule" type="System.IdentityModel.Services.SessionAuthenticationModule, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="managedHandler" /> 
    </modules> 
    <validation validateIntegratedModeConfiguration="false" /> 
    </system.webServer> 
    <system.identityModel> 
    <identityConfiguration> 
     <audienceUris> 
     <add value="urn:webapisecurity" /> 
     </audienceUris> 
     <claimsAuthorizationManager type="Thinktecture.IdentityServer.Ofi.AuthorizationManager, Thinktecture.IdentityServer.Ofi, Version=1.0.0.0, Culture=neutral" /> 
     <claimsAuthenticationManager type="Thinktecture.IdentityServer.Ofi.AuthenticationManager, Thinktecture.IdentityServer.Ofi, Version=1.0.0.0, Culture=neutral" /> 
     <certificateValidation certificateValidationMode="None" /> 
     <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> 
     <trustedIssuers> 
      <add thumbprint="489116B0FCF14DF66D47AE272C3B9FD867D0E050" /> 
     </trustedIssuers> 
     </issuerNameRegistry> 
    </identityConfiguration> 
    </system.identityModel> 
    <system.identityModel.services> 
    <federationConfiguration> 
     <cookieHandler requireSsl="false" /> 
     <wsFederation passiveRedirectEnabled="true" issuer="https://srv:4443/issue/wsfed" realm="urn:webapisecurity" reply="http://localhost:64346/" requireHttps="false" /> 
    </federationConfiguration> 
    </system.identityModel.services> 
    <runtime> 
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" /> 
     <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" /> 
     <bindingRedirect oldVersion="0.0.0.0-1.5.2.14234" newVersion="1.5.2.14234" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" /> 
     <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" /> 
     <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" /> 
     <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Web.Http" publicKeyToken="31bf3856ad364e35" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" /> 
     </dependentAssembly> 
     <dependentAssembly> 
     <assemblyIdentity name="System.Net.Http.Formatting" publicKeyToken="31bf3856ad364e35" culture="neutral" /> 
     <bindingRedirect oldVersion="0.0.0.0-5.1.0.0" newVersion="5.1.0.0" /> 
     </dependentAssembly> 
    </assemblyBinding> 
    </runtime> 
    <entityFramework> 
    <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework" /> 
    <providers> 
     <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /> 
    </providers> 
    </entityFramework> 
</configuration> 

Bununla, FedAuth yemeklerini görebiliyorum. yani tarayıcıda ayarlanır ve WebApi'de doğrulama yapar.

+0

Yea bu da çalışıyor, ancak verdiğim çözüm, SSO'yu istiyorsanız daha uygundur. –

+0

Çözümünüzü gönderdiğiniz için teşekkürler. Bu bana yardım etti! Ayrıca Idsrv'ye yönlendirmek yerine bir proxy üzerinden giriş yapmak da güzel. Tekrar teşekkür ederim. – StefanHa

+0

Size yardımcı olmaktan memnun oldum! – cdiazal

6

Yapmanız gereken birkaç şey var. Jeton taleplerini yapabilecek bir OAuth istemcisi oluşturun ve bunu, web api uç noktalarınıza erişmenizi sağlayan kimlik sunucusundan erişim sağlayıcıları almak için kullanın. Bunu yapmak için OAuth istemcinizin örtülü akışa sahip olması gerekir. Daha sonra OAuth istemcinizin oturum açmasına izin vermek için bir açılır pencereden Kimlik sunucusuna bir giriş isteği yaparsınız. OAuth istemci ayrıntılarınızda, oturum açma isteğinin sorgu dizesinde, bir OAuth istemci yapılandırması olan Idsrv'ye geçmeniz gerekir. OAuth istemcisi için Idsrv yönetici panelinde tanımlanan neyi olurdu, bunu parametreleyebilir ve OAuth2/authorzie url bunu ekleriz:

var url = authService.getIdpOauthEndpointUrl() + "?" + $.param(authService.getOAuthConfig()); 
        window.open(url, "Login", "height=500,width=350"); 

:

getIdpOauthEndpointUrl: function() { 
       return "https://192.168.1.9/issue/oauth2/authorize"; 
}, 
getOAuthConfig: function() { 
       return { 
        client_id: "Your Oauth CLient ID that you specifie din Identity Server", 
        scope: "The scope of your RP", 
        response_type: "token", 
        redirect_uri: "https://..YourAngularAppUrl/AuthCallback.html" 
       }; 
} 

sonra giriş penceresini açmak OAuth istemcinizde inIdsrv uygulamasında bir yönlendirme URL'si belirtmeniz gerekir, bizim durumumuzda:

https://YourAngularAppUrl/AuthCallback.html 

OAuth istemci ayrıntıları ile birlikte kimlik sunucusuna giriş isteğini ilettiğiniz şeydir. AuthCallback.html sayfası, bir sorgu dizesinde bu sayfaya idsrv tarafından döndürülen erişim belirtecini ayıklamaz ve bunu açısal uygulamanıza aktarır, bunu size nasıl yaptığını, ancak erişim belirtecinin $http başlıklarınıza koyulması gerekir . Benim index.html

<script src="/Scripts/jquery-2.0.3.js"></script> 
<script src="/Scripts/jquery.ba-bbq.min.js"></script> 

<script type="text/javascript"> 
    var params = $.deparam.fragment(location.hash.substring(1)); 

    window.opener.oAuthCallback(params); 
    window.close(); 
</script> 

OAuthCallback işlev benim kabuk sayfasında tanımlanır ve içine verdi jetonu geçen sorumludur:

erişim belirteci

bu gibi AuthCallback.html sayfasında çıkarılabilir açısal uygulamam ve onu $http başlıklarına yerleştir.

function oAuthCallback(OAUTHTOKEN) { 
    angular.element(window.document).scope().setHttpAuthHeaderAndAuthenticate(OAUTHTOKEN); 
} 

setHttpAuthHeaderAndAuthenticate() işlevi benim $rootScope tanımlanır ve bu $http authorizaiton başlıklarını da jetonu koyar:

$http.defaults.headers.common.Authorization = 'Bearer ' + OAUTHTOKEN["access_token"];

Christian Weyer tarafından this post göz at Biz' tam olarak ne yapar Yapıyor, ama yine de aynı konsept, bir knockout/web-api uygulaması.

Bir sonraki adım, web api'nizin idsrv'den erişim belirtecini kabul etmesini söylemek, bu basittir;

public static void Configure(HttpConfiguration config) 
     { 
      var authConfig = new AuthenticationConfiguration(); 

      authConfig.AddJsonWebToken(
    YourIdsrvSiteId, YourRpsScope/Relam,YourRpsSymmetricSigningKey 
); 

      config.MessageHandlers.Add(new AuthenticationHandler(authNConfig)); 
     } 

Ayrıca iddialarını değiştirebilmek için buraya ClaimsAuthenticationManager ve ClaimsAuthorizationManager tanımlayabiliriz ve Grant/web API kaynakları sto acces Reddet. Yine tüm bu, Christian Weyer'ın yazılarına dahil. Bu yardımcı olur umarım. Angularjs ise

:

+0

Ben de bu şekilde deneyeceğim, öğrenecek çok şey var! Teşekkür ederim! – cdiazal

İlgili konular