AJAX对REST端点固定电话与Thinktecture的IdentityServer STS [英] AJAX call against REST endpoint secured with Thinktecture's IdentityServer STS

查看:158
本文介绍了AJAX对REST端点固定电话与Thinktecture的IdentityServer STS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些电视剧制作反对,我已经获得了与开箱IdentityServer STS的ServiceStack REST服务的电话。

I'm having some dramas making a call against a ServiceStack REST service which I've secured with an out of the box IdentityServer STS.

我正在对REST端点AJAX调用,而我不知道的人会设置一个登录过程如何得到一个安全令牌传递。剩下的终点是在不同的域进行调用的网站。我发现的信息,到目前为止一切似乎都围绕在客户端进行调用以受保护的资源得到了302重定向到identityserver登录页面,然后经过身份验证成功得到302重定向到任何领域或过程回复取决于配置。我迷上这一切都正确,它的伟大工程,如果我通过REST服务只是浏览。然而,随着问候我的web应用程序,AJAX和302S是不完全的最好的朋友,所以理论上讲,我认为我想有来自同一ServiceStack网站需要用户名和密码,并返回一个安全令牌没有休息端点任何重定向的并发症(我来处理我的web应用程序自身的401重定向,当我关掉passiveRedirectEnabled在web.config中,我会得到)。怎样你有什么想法可能实现这一目标与IdentityServer?

I'm making an AJAX call against the REST endpoint, and I'm not sure how one might setup a logon procedure to get a security token to pass. The REST endpoint is on a different domain than the website making the call. The info that I've found so far all seems to revolve around the procedure where the client makes a call to the secured resource gets a 302 redirect to the identityserver logon page, then after successful authentication gets a 302 redirect to either the realm or the reply depending on the configuration. I've hooked all this up correctly and it works great if I'm simply browsing through the REST services. However with regards to my web app, AJAX and 302s aren't exactly best friends, so ideally what I think I'd like to have is a REST endpoint from the same ServiceStack website that takes a username and password and returns a security token without the complication of any redirects (I'll handle the 401 redirects within my web application itself which I'll get when I turn off passiveRedirectEnabled in the web.config). Any thoughts on how one might achieve this with IdentityServer?

干杯, 克林特。

推荐答案

完成答案与充分休息端点:

Completing the answer with the full REST endpoint:

在ServiceStack Web应用程序:

In the ServiceStack web app:

路线在AppHost.cs登录端点是这样的:

Route to the logon endpoint in AppHost.cs with something like:

public override void Configure(Container container)
{
    Routes.Add<Logon>("/logon", "POST");
}

此外,还有一个简单的用户名/密码请求DTO

Then there's a simple username/password Request DTO

public class Logon
{
    public string UserName { get; set; }
    public string Password { get; set; }
}

和响应DTO

响应DTO只需要处理POST - 是的,你可以添加URL /密码 作为URL中的一个GET请求参数,但是这听起来并不像它的建议。 事实上,你可能常把这个信息在HTTP请求的Authorization头 但是这使得在ServiceStack有点困难你的工作。

Response DTO only needs to handle the POST - yes, you could add the URL/Password as parameters in the URL for a GET request, but this does not sound like it's recommended. In fact, you'd probably normally put this info in the Authorization header of the HTTP request but this makes your job in ServiceStack a little harder.

public class LogonService : Service
{
    public object Post(Logon request)
    {
        var securityToken = GetSaml2SecurityToken(request.UserName, request.Password, "https://myserver/identityserverwebapp/issue/wstrust/mixed/username", "http://myserver/servicestackwebapp/");

        return SerializeRequestSecurityTokenResponse(securityToken);
    }

    private RequestSecurityTokenResponse GetSaml2SecurityToken(string username, string password, string endpointAddress, string realm)
    {
        var factory = new WSTrustChannelFactory(new UserNameWSTrustBinding(SecurityMode.TransportWithMessageCredential),
            new EndpointAddress(endpointAddress))
        {
            TrustVersion = TrustVersion.WSTrust13
        };

        factory.Credentials.UserName.UserName = username;
        factory.Credentials.UserName.Password = password;

        var channel = (WSTrustChannel)factory.CreateChannel();
        RequestSecurityTokenResponse requestSecurityTokenResponse;

        channel.Issue(new RequestSecurityToken
        {
            TokenType = "http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0",
            AppliesTo = new EndpointReference(realm),
            RequestType = RequestTypes.Issue,
            KeyType = KeyTypes.Bearer,
        }, out requestSecurityTokenResponse);

        return requestSecurityTokenResponse;
    }

    private string SerializeRequestSecurityTokenResponse(RequestSecurityTokenResponse requestSecurityTokenResponse)
    {
        var serializer = new WSTrust13ResponseSerializer();
        var context = new WSTrustSerializationContext(FederatedAuthentication.FederationConfiguration.IdentityConfiguration.SecurityTokenHandlerCollectionManager);
        var stringBuilder = new StringBuilder(128);

        using (var writer = XmlWriter.Create(new StringWriter(stringBuilder), new XmlWriterSettings { OmitXmlDeclaration = true}))
        {
            serializer.WriteXml(requestSecurityTokenResponse, writer, context);
            writer.Flush();
            return stringBuilder.ToString();
        }
    }
}

在ServiceStack Web应用程序的Web.config应该相当类似这样:

The ServiceStack web app Web.config should look fairly similar to this:

<?xml version="1.0"?>
<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" />
  </configSections>
  <location path="FederationMetadata">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <!-- to allow the logon route without requiring authentication first. -->
  <location path="logon">
    <system.web>
      <authorization>
        <allow users="*" />
      </authorization>
    </system.web>
  </location>
  <system.web>
    <httpHandlers>
      <add path="*" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" />
    </httpHandlers>
    <compilation debug="true" />
    <authentication mode="None" />
    <authorization>
      <deny users="?" />
    </authorization>
    <httpRuntime targetFramework="4.5" requestValidationMode="4.5" />
  </system.web>
  <system.webServer>
    <modules runAllManagedModulesForAllRequests="true">
        <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" />
    <handlers>
      <add path="*" name="ServiceStack.Factory" type="ServiceStack.WebHost.Endpoints.ServiceStackHttpHandlerFactory, ServiceStack" verb="*" preCondition="integratedMode" resourceType="Unspecified" allowPathInfo="true" />
    </handlers>
  </system.webServer>
  <system.identityModel>
    <identityConfiguration>
      <audienceUris>
        <add value="http://myserver/servicestackwebapp/" />
      </audienceUris>
      <issuerNameRegistry type="System.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
        <trustedIssuers>
          <add thumbprint="B6E05E14243FB7D76D5B660532520FB94679AA01" name="http://mycertificatefriendlyname" />
        </trustedIssuers>
      </issuerNameRegistry>
      <certificateValidation certificateValidationMode="None" />
      <securityTokenHandlers>
        <securityTokenHandlerConfiguration saveBootstrapContext="true" />
      </securityTokenHandlers>
    </identityConfiguration>
  </system.identityModel>
  <system.identityModel.services>
    <federationConfiguration>
      <cookieHandler requireSsl="false" />
      <wsFederation passiveRedirectEnabled="false" issuer="https://myserver/identityserverwebapp/issue/wsfed" realm="http://myserver/servicestackwebapp/" requireHttps="false" />
    </federationConfiguration>
  </system.identityModel.services>
</configuration>

最后,进行身份验证与REST端点,POST的用户名和密码servicestackwebapp的登录端点一个简单的JavaScript客户端应用程序,然后当您收到回应,帖子说回境界 - 这样设置该FedAuth饼干当前会话,这样你就不必去想令牌管理客户端了。

And finally, to authenticate a simple Javascript client app with the REST endpoint, POST the username and password to the logon endpoint of the servicestackwebapp, and then when you receive the response, post that back to the realm - doing so sets up the FedAuth cookies for your current session so you don't have to think about the token management client-side anymore.

$.ajax({
    type: "POST",
    url: "/servicestackwebapp/logon",
    dataType: "text",
    data: { UserName: "myuser", Password: "mypassword" },
    success: function (data) {
        $.ajax({
            type: "POST",
            url: "/servicestackwebapp/",
            data: "wa=wsignin1.0&wresult=" + encodeURIComponent(data)
        });
    }
});

另外,我要指出,上述所有的HTTP端点而是应该去通过HTTPS - 别傻就像我在我的例子已经完成,并通过HTTP发送明文要求

Also, I should note that all of the HTTP endpoints above should instead be going over HTTPS - don't be silly like I've done in my example and send clear-text claims over HTTP.

另外后我会实现我的解决方案,我发现这个:的http:// msdn.microsoft.com/en-us/library/hh446531.aspx ......我希望我才发现了它,但是这是令人欣慰知道我实现了类似微软的例子的东西 - 我们在发散,他们转换为简单的Web令牌点 - 我把它作为一个SAML令牌和传递(连载)到客户端,而不是。

Also after I'd implemented my solution I found this: http://msdn.microsoft.com/en-us/library/hh446531.aspx ... I wish I'd found it before, but it's reassuring to know I've implemented something similar to the Microsoft example - we diverge at the point where they convert to a Simple Web Token - I keep it as a SAML token and pass that (serialized) to the client instead.

这篇关于AJAX对REST端点固定电话与Thinktecture的IdentityServer STS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆