Завершение ответ с полным REST конечной точки:
В ServiceStack веб-приложение:
пути к конечной точке входа в AppHost.cs с чем-то вроде:
public override void Configure(Container container)
{
Routes.Add<Logon>("/logon", "POST");
}
Тогда есть простое имя пользователя/пароль Запрос DTO
public class Logon
{
public string UserName { get; set; }
public string Password { get; set; }
}
И соответственно onse DTO
Ответ DTO должен обрабатывать только POST - да, вы можете добавить URL/пароль в качестве параметров URL-адреса для запроса GET, но это не похоже на то, что это рекомендуется. Фактически, вы, вероятно, обычно помещаете эту информацию в заголовок авторизации HTTP-запроса , но это затрудняет вашу работу в ServiceStack.
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.config должен выглядеть довольно похож на это:
<?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>
И, наконец, для проверки подлинности простого клиента приложения Javascript с REST конечной точкой, POST именем пользователя и паролем к конечной точки входа в систему servicestackwebapp, а затем, когда вы получите ответ, отправьте это обратно в область - таким образом настройте файлы cookie FedAuth для вашего текущего сеанса, поэтому вам больше не нужно думать о клиентской стороне управления токеном.
$.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.
Также после того, как я реализовал свое решение, я нашел это: http://msdn.microsoft.com/en-us/library/hh446531.aspx ... Хотел бы я найти его раньше, но я уверен, что я реализовал нечто похожее на пример Microsoft - мы расходимся в где они конвертируются в простой веб-токен - я сохраняю его как токен SAML и передаю его (сериализованному) клиенту.