PageRenderTime 27ms CodeModel.GetById 30ms RepoModel.GetById 1ms app.codeStats 0ms

/src/Libraries/Thinktecture.IdentityServer.Protocols/WSFederation/HrdController.cs

https://github.com/ELEMENTSECM/Thinktecture.IdentityServer.v2
C# | 613 lines | 495 code | 101 blank | 17 comment | 58 complexity | 0f4193bfa5070530c904f45825a27512 MD5 | raw file
  1. /*
  2. * Copyright (c) Dominick Baier, Brock Allen. All rights reserved.
  3. * see license.txt
  4. */
  5. using System.IO;
  6. using System.IdentityModel.Services.Configuration;
  7. using System.Text;
  8. using System.Xml;
  9. using System.Xml.Linq;
  10. using BrockAllen.OAuth2;
  11. using Microsoft.IdentityModel.Claims;
  12. using Microsoft.IdentityModel.Protocols.Saml2;
  13. using Microsoft.IdentityModel.Protocols.Saml2.Constants;
  14. using Microsoft.IdentityModel.Protocols.WSFederation.Metadata;
  15. using Microsoft.IdentityModel.SecurityTokenService;
  16. using Newtonsoft.Json.Linq;
  17. using System;
  18. using System.Collections.Generic;
  19. using System.ComponentModel.Composition;
  20. using System.IdentityModel.Selectors;
  21. using System.IdentityModel.Services;
  22. using System.IdentityModel.Tokens;
  23. using System.Linq;
  24. using System.Threading.Tasks;
  25. using System.Web;
  26. using System.Web.Mvc;
  27. using Thinktecture.IdentityServer.Models;
  28. using Thinktecture.IdentityServer.Repositories;
  29. using Thinktecture.IdentityServer.TokenService;
  30. using Lifetime = Microsoft.IdentityModel.Protocols.WSTrust.Lifetime;
  31. using RequestSecurityTokenResponse = Microsoft.IdentityModel.Protocols.WSTrust.RequestSecurityTokenResponse;
  32. using RequestedSecurityToken = Microsoft.IdentityModel.Protocols.WSTrust.RequestedSecurityToken;
  33. using Claim = System.Security.Claims.Claim;
  34. using ClaimTypes = System.Security.Claims.ClaimTypes;
  35. using ClaimValueTypes = System.Security.Claims.ClaimValueTypes;
  36. using ClaimsIdentity = System.Security.Claims.ClaimsIdentity;
  37. using ClaimsPrincipal = System.Security.Claims.ClaimsPrincipal;
  38. using FederatedAuthentication = Microsoft.IdentityModel.Web.FederatedAuthentication;
  39. namespace Thinktecture.IdentityServer.Protocols.WSFederation
  40. {
  41. public class HrdController : Controller
  42. {
  43. const string _cookieName = "hrdsignout";
  44. const string _cookieNameRememberHrd = "hrdSelection";
  45. const string _cookieContext = "idsrvcontext";
  46. [Import]
  47. public IConfigurationRepository ConfigurationRepository { get; set; }
  48. [Import]
  49. public IIdentityProviderRepository IdentityProviderRepository { get; set; }
  50. public HrdController()
  51. {
  52. Container.Current.SatisfyImportsOnce(this);
  53. }
  54. public HrdController(IConfigurationRepository configurationRepository, IIdentityProviderRepository identityProviderRepository)
  55. {
  56. IdentityProviderRepository = identityProviderRepository;
  57. ConfigurationRepository = configurationRepository;
  58. }
  59. public ActionResult Issue()
  60. {
  61. Tracing.Verbose("HRD endpoint called.");
  62. var message = WSFederationMessage.CreateFromUri(HttpContext.Request.Url);
  63. // sign in
  64. var signinMessage = message as SignInRequestMessage;
  65. if (signinMessage != null)
  66. {
  67. return ProcessSignInRequest(signinMessage);
  68. }
  69. // sign out
  70. var signoutMessage = message as SignOutRequestMessage;
  71. if (signoutMessage != null)
  72. {
  73. return ProcessSignOut(signoutMessage);
  74. }
  75. return View("Error");
  76. }
  77. [HttpPost]
  78. [ActionName("Issue")]
  79. public ActionResult IssueResponse()
  80. {
  81. if (Request.Form.HasKeys())
  82. {
  83. if (Request.Form["SAMLResponse"] != null)
  84. {
  85. var samlResponse = Request.Form["SAMLResponse"];
  86. var responseDecoded = Encoding.UTF8.GetString(Convert.FromBase64String(HttpUtility.HtmlDecode(samlResponse)));
  87. Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityToken token;
  88. using (var sr = new StringReader(responseDecoded))
  89. {
  90. using (var reader = XmlReader.Create(sr))
  91. {
  92. reader.ReadToFollowing("Assertion", "urn:oasis:names:tc:SAML:2.0:assertion");
  93. var coll = Microsoft.IdentityModel.Tokens.SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection();
  94. token = (Microsoft.IdentityModel.Tokens.Saml2.Saml2SecurityToken)coll.ReadToken(reader.ReadSubtree());
  95. }
  96. }
  97. var realm = token.Assertion.Conditions.AudienceRestrictions[0].Audiences[0].ToString();
  98. var issuer = token.Assertion.Issuer.Value;
  99. var rstr = new RequestSecurityTokenResponse
  100. {
  101. TokenType = Constants.TokenKeys.TokenType,
  102. RequestType = Constants.TokenKeys.RequestType,
  103. KeyType = Constants.TokenKeys.KeyType,
  104. Lifetime = new Lifetime(token.Assertion.IssueInstant, token.Assertion.Conditions.NotOnOrAfter),
  105. AppliesTo = new System.ServiceModel.EndpointAddress(new Uri(realm)),
  106. RequestedSecurityToken = new RequestedSecurityToken(GetElement(responseDecoded))
  107. };
  108. var principal = GetClaimsIdentity(rstr);
  109. if (principal != null)
  110. {
  111. var claimsPrinciple = Microsoft.IdentityModel.Claims.ClaimsPrincipal.CreateFromPrincipal(principal);
  112. var requestMessage = new Microsoft.IdentityModel.Protocols.WSFederation.SignInRequestMessage(new Uri("http://foo"), realm);
  113. var ipc = new SamlTokenServiceConfiguration(issuer);
  114. SecurityTokenService identityProvider = new SamlTokenService(ipc);
  115. var responseMessage = Microsoft.IdentityModel.Web.FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(requestMessage, claimsPrinciple, identityProvider);
  116. new SignInSessionsManager(HttpContext, _cookieName, ConfigurationRepository.Global.MaximumTokenLifetime).AddEndpoint(responseMessage.BaseUri.AbsoluteUri);
  117. Microsoft.IdentityModel.Web.FederatedPassiveSecurityTokenServiceOperations.ProcessSignInResponse(responseMessage, System.Web.HttpContext.Current.Response);
  118. }
  119. //return new EmptyResult();
  120. }
  121. var fam = new WSFederationAuthenticationModule { FederationConfiguration = new FederationConfiguration() };
  122. if (fam.CanReadSignInResponse(Request))
  123. {
  124. var responseMessage = fam.GetSignInResponseMessage(Request);
  125. return ProcessSignInResponse(responseMessage, fam.GetSecurityToken(Request));
  126. }
  127. }
  128. return View("Error");
  129. }
  130. #region SAML2 Helper
  131. private static XmlElement GetElement(string xml)
  132. {
  133. var doc = new XmlDocument();
  134. doc.LoadXml(xml);
  135. return doc.DocumentElement;
  136. }
  137. public static XElement ToXElement(XmlElement xml)
  138. {
  139. var doc = new XmlDocument();
  140. doc.AppendChild(doc.ImportNode(xml, true));
  141. return XElement.Parse(doc.InnerXml);
  142. }
  143. private static IClaimsPrincipal GetClaimsIdentity(RequestSecurityTokenResponse rstr)
  144. {
  145. var rstrXml = rstr.RequestedSecurityToken.SecurityTokenXml;
  146. var xnm = new XmlNamespaceManager(rstrXml.OwnerDocument.NameTable);
  147. xnm.AddNamespace(Microsoft.IdentityModel.Tokens.Saml2.Saml2Constants.Prefix, Microsoft.IdentityModel.Tokens.Saml2.Saml2Constants.Namespace);
  148. XNamespace ast = "urn:oasis:names:tc:SAML:2.0:assertion";
  149. var xElement = ToXElement(rstrXml);
  150. var xAssertionElement = xElement.Element(ast + "Assertion");
  151. if (xAssertionElement != null)
  152. {
  153. var xAttributeStatement = xAssertionElement.Element(ast + "AttributeStatement");
  154. if (xAttributeStatement != null)
  155. {
  156. var xAttributes = xAttributeStatement.Elements(ast + "Attribute");
  157. IClaimsIdentity claimsIdentity = new Microsoft.IdentityModel.Claims.ClaimsIdentity();
  158. foreach (var element in xAttributes)
  159. {
  160. var claimType = element.Attribute("NameFormat") + "/" + element.Attribute("Name");
  161. var value = element.Value;
  162. var xAttribute = element.Attribute("Name");
  163. if (xAttribute != null && xAttribute.Value == "urn:FirstName")
  164. claimsIdentity.Claims.Add(new Microsoft.IdentityModel.Claims.Claim(ClaimTypes.Name, element.Value));
  165. claimsIdentity.Claims.Add(new Microsoft.IdentityModel.Claims.Claim(claimType, value ?? ""));
  166. }
  167. var claimsIdentitycol = new ClaimsIdentityCollection(new[] { claimsIdentity });
  168. return Microsoft.IdentityModel.Claims.ClaimsPrincipal.CreateFromIdentities(claimsIdentitycol);
  169. }
  170. }
  171. return null;
  172. }
  173. #endregion
  174. #region Helper
  175. private ActionResult ProcessSignInRequest(SignInRequestMessage message)
  176. {
  177. if (!string.IsNullOrWhiteSpace(message.HomeRealm))
  178. {
  179. return RedirectToIdentityProvider(message);
  180. }
  181. else
  182. {
  183. var pastHRDSelection = GetRememberHRDCookieValue();
  184. if (String.IsNullOrWhiteSpace(pastHRDSelection))
  185. {
  186. return ShowHomeRealmSelection(message);
  187. }
  188. else
  189. {
  190. return ProcessHomeRealmFromCookieValue(message, pastHRDSelection);
  191. }
  192. }
  193. }
  194. private ActionResult ProcessHomeRealmFromCookieValue(SignInRequestMessage message, string pastHRDSelection)
  195. {
  196. message.HomeRealm = pastHRDSelection;
  197. return ProcessSignInRequest(message);
  198. }
  199. private ActionResult ProcessSignOut(SignOutRequestMessage message)
  200. {
  201. // check for return url
  202. if (!string.IsNullOrWhiteSpace(message.Reply))
  203. {
  204. ViewBag.ReturnUrl = message.Reply;
  205. }
  206. // check for existing sign in sessions
  207. var mgr = new SignInSessionsManager(HttpContext, _cookieName);
  208. var realms = mgr.GetEndpoints();
  209. mgr.ClearEndpoints();
  210. //System.IdentityModel.Services.FederatedAuthentication.SessionAuthenticationModule.SignOut();
  211. //System.IdentityModel.Services.FederatedAuthentication.SessionAuthenticationModule.DeleteSessionTokenCookie();
  212. //System.IdentityModel.Services.FederatedAuthentication.WSFederationAuthenticationModule.SignOut();
  213. return View("Signout", realms);
  214. }
  215. private ActionResult ProcessSignInResponse(SignInResponseMessage responseMessage, SecurityToken token)
  216. {
  217. var principal = ValidateToken(token);
  218. var issuerName = principal.Claims.First().Issuer;
  219. principal.Identities.First().AddClaim(new Claim(Constants.Claims.IdentityProvider, issuerName, ClaimValueTypes.String, Constants.InternalIssuer));
  220. var context = GetContextCookie();
  221. var message = new SignInRequestMessage(new Uri("http://foo"), context.Realm);
  222. message.Context = context.Wctx;
  223. // issue token and create ws-fed response
  224. var wsFedResponse = FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(
  225. message,
  226. principal,
  227. TokenServiceConfiguration.Current.CreateSecurityTokenService());
  228. // set cookie for single-sign-out
  229. new SignInSessionsManager(HttpContext, _cookieName, ConfigurationRepository.Global.MaximumTokenLifetime)
  230. .SetEndpoint(context.WsFedEndpoint);
  231. return new WSFederationResult(wsFedResponse, requireSsl: ConfigurationRepository.WSFederation.RequireSslForReplyTo);
  232. }
  233. IEnumerable<IdentityProvider> GetEnabledWSIdentityProviders()
  234. {
  235. return IdentityProviderRepository.GetAll().Where(
  236. x => x.Enabled && x.Type == IdentityProviderTypes.WSStar);
  237. }
  238. IEnumerable<IdentityProvider> GetVisibleIdentityProviders()
  239. {
  240. return IdentityProviderRepository.GetAll().Where(
  241. x => x.Enabled && x.ShowInHrdSelection);
  242. }
  243. private ClaimsPrincipal ValidateToken(SecurityToken token)
  244. {
  245. var config = new SecurityTokenHandlerConfiguration();
  246. config.AudienceRestriction.AudienceMode = AudienceUriMode.Always;
  247. config.AudienceRestriction.AllowedAudienceUris.Add(new Uri(ConfigurationRepository.Global.IssuerUri));
  248. var registry = new IdentityProviderIssuerNameRegistry(GetEnabledWSIdentityProviders());
  249. config.IssuerNameRegistry = registry;
  250. config.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
  251. config.CertificateValidator = X509CertificateValidator.None;
  252. var handler = SecurityTokenHandlerCollection.CreateDefaultSecurityTokenHandlerCollection(config);
  253. var identity = handler.ValidateToken(token).First();
  254. return new ClaimsPrincipal(identity);
  255. }
  256. private ActionResult ShowHomeRealmSelection(SignInRequestMessage message)
  257. {
  258. var idps = GetVisibleIdentityProviders();
  259. if (idps.Count() == 1)
  260. {
  261. var ip = idps.First();
  262. message.HomeRealm = ip.Name;
  263. Tracing.Verbose("Only one HRD option available: " + message.HomeRealm);
  264. return RedirectToIdentityProvider(ip, message);
  265. }
  266. else
  267. {
  268. Tracing.Verbose("HRD selection screen displayed.");
  269. var vm = new HrdViewModel(message, idps);
  270. return View("HRD", vm);
  271. }
  272. }
  273. private string GetRememberHRDCookieValue()
  274. {
  275. if (Request.Cookies.AllKeys.Contains(_cookieNameRememberHrd))
  276. {
  277. var cookie = Request.Cookies[_cookieNameRememberHrd];
  278. var realm = cookie.Value;
  279. var idps = GetVisibleIdentityProviders().Where(x => x.Name == realm);
  280. var idp = idps.SingleOrDefault();
  281. if (idp == null)
  282. {
  283. Tracing.Verbose("Past HRD selection from cookie not found in current HRD list. Past value was: " + realm);
  284. SetRememberHRDCookieValue(null);
  285. }
  286. return realm;
  287. }
  288. return null;
  289. }
  290. private void SetRememberHRDCookieValue(string realm)
  291. {
  292. var cookie = new HttpCookie(_cookieNameRememberHrd);
  293. if (String.IsNullOrWhiteSpace(realm))
  294. {
  295. realm = ".";
  296. cookie.Expires = DateTime.UtcNow.AddYears(-1);
  297. }
  298. else
  299. {
  300. cookie.Expires = DateTime.Now.AddMonths(1);
  301. }
  302. cookie.Value = realm;
  303. cookie.HttpOnly = true;
  304. cookie.Secure = true;
  305. cookie.Path = Request.ApplicationPath;
  306. Response.Cookies.Add(cookie);
  307. }
  308. [HttpPost]
  309. [ValidateAntiForgeryToken]
  310. [ActionName("Select")]
  311. public ActionResult ProcessHRDSelection(string idp, string originalSigninUrl, bool rememberHRDSelection = false)
  312. {
  313. Tracing.Verbose("HRD selected: " + idp);
  314. var uri = new Uri(originalSigninUrl);
  315. var message = WSFederationMessage.CreateFromUri(uri);
  316. var signinMessage = message as SignInRequestMessage;
  317. var ip = GetVisibleIdentityProviders().Where(x => x.Name == idp).FirstOrDefault();
  318. if (ip == null || signinMessage == null) return View("Error");
  319. try
  320. {
  321. if (rememberHRDSelection)
  322. {
  323. SetRememberHRDCookieValue(idp);
  324. }
  325. if (ip.Type == IdentityProviderTypes.WSStar)
  326. {
  327. signinMessage.HomeRealm = ip.Name;
  328. return RedirectToIdentityProvider(ip, signinMessage);
  329. }
  330. if (ip.Type == IdentityProviderTypes.OAuth2)
  331. {
  332. return ProcessOAuth2SignIn(ip, signinMessage);
  333. }
  334. if (ip.Type == IdentityProviderTypes.Saml2)
  335. {
  336. return ProcessSaml2SignIn(ip, signinMessage);
  337. }
  338. }
  339. catch (Exception ex)
  340. {
  341. Tracing.Error(ex.ToString());
  342. }
  343. return View("Error");
  344. }
  345. private ActionResult ProcessSaml2SignIn(IdentityProvider ip, SignInRequestMessage request)
  346. {
  347. if (ip.Enabled)
  348. {
  349. var saml2ProtocolSerializer = new Saml2ProtocolSerializer();
  350. var protocolBinding = ProtocolBindings.HttpRedirect;
  351. HttpBindingSerializer httpBindingSerializer = new HttpRedirectBindingSerializer(saml2ProtocolSerializer);
  352. var authenticationRequest = new AuthenticationRequest()
  353. {
  354. Issuer =
  355. new Microsoft.IdentityModel.Tokens.Saml2.Saml2NameIdentifier(request.Realm.TrimEnd('/'), new Uri(ip.WSFederationEndpoint)),
  356. Destination = new Uri(ip.WSFederationEndpoint)
  357. };
  358. var messageContainer = new MessageContainer(authenticationRequest, new ProtocolEndpoint(protocolBinding, new Uri(ip.WSFederationEndpoint + "/signon.ashx")));
  359. var httpMessage = httpBindingSerializer.Serialize(messageContainer);
  360. httpBindingSerializer.WriteHttpMessage(new HttpResponseWrapper(System.Web.HttpContext.Current.Response), httpMessage);
  361. ControllerContext.HttpContext.ApplicationInstance.CompleteRequest();
  362. // return new EmptyResult();
  363. }
  364. return View("Error");
  365. }
  366. private ActionResult RedirectToIdentityProvider(SignInRequestMessage request)
  367. {
  368. IdentityProvider idp = null;
  369. if (IdentityProviderRepository.TryGet(request.HomeRealm, out idp) && idp.Enabled)
  370. {
  371. return RedirectToIdentityProvider(idp, request);
  372. }
  373. return View("Error");
  374. }
  375. private ActionResult RedirectToIdentityProvider(IdentityProvider identityProvider, SignInRequestMessage request)
  376. {
  377. var message = new SignInRequestMessage(new Uri(identityProvider.WSFederationEndpoint), ConfigurationRepository.Global.IssuerUri);
  378. SetContextCookie(request.Context, request.Realm, identityProvider.WSFederationEndpoint);
  379. return new RedirectResult(message.WriteQueryString());
  380. }
  381. private void SetContextCookie(string wctx, string realm, string wsfedEndpoint)
  382. {
  383. var j = JObject.FromObject(new Context { Wctx = wctx, Realm = realm, WsFedEndpoint = wsfedEndpoint });
  384. var cookie = new HttpCookie(_cookieContext, j.ToString())
  385. {
  386. Secure = true,
  387. HttpOnly = true,
  388. Path = HttpRuntime.AppDomainAppVirtualPath
  389. };
  390. Response.Cookies.Add(cookie);
  391. }
  392. private Context GetContextCookie()
  393. {
  394. var cookie = Request.Cookies[_cookieContext];
  395. if (cookie == null)
  396. {
  397. throw new InvalidOperationException("cookie");
  398. }
  399. var json = JObject.Parse(HttpUtility.UrlDecode(cookie.Value));
  400. cookie.Value = "";
  401. cookie.Expires = new DateTime(2000, 1, 1);
  402. cookie.Path = HttpRuntime.AppDomainAppVirtualPath;
  403. Response.SetCookie(cookie);
  404. return json.ToObject<Context>();
  405. }
  406. internal class Context
  407. {
  408. public string Wctx { get; set; }
  409. public string Realm { get; set; }
  410. public string WsFedEndpoint { get; set; }
  411. }
  412. internal class OAuth2Context : Context
  413. {
  414. public int IdP { get; set; }
  415. }
  416. private void SetOAuthContextCookie(OAuth2Context ctx)
  417. {
  418. var j = JObject.FromObject(ctx);
  419. var cookie = new HttpCookie("idsrvoauthcontext", j.ToString());
  420. cookie.Secure = true;
  421. cookie.HttpOnly = true;
  422. cookie.Path = Request.ApplicationPath;
  423. Response.Cookies.Add(cookie);
  424. }
  425. private OAuth2Context GetOAuthContextCookie()
  426. {
  427. var cookie = Request.Cookies["idsrvoauthcontext"];
  428. if (cookie == null)
  429. {
  430. throw new InvalidOperationException("cookie");
  431. }
  432. var json = JObject.Parse(HttpUtility.UrlDecode(cookie.Value));
  433. var data = json.ToObject<OAuth2Context>();
  434. var deletecookie = new HttpCookie("idsrvoauthcontext", ".");
  435. deletecookie.Secure = true;
  436. deletecookie.HttpOnly = true;
  437. deletecookie.Path = Request.ApplicationPath;
  438. Response.Cookies.Add(deletecookie);
  439. return data;
  440. }
  441. private ActionResult ProcessOAuth2SignIn(IdentityProvider ip, SignInRequestMessage request)
  442. {
  443. var ctx = new OAuth2Context
  444. {
  445. Wctx = request.Context,
  446. Realm = request.Realm,
  447. IdP = ip.ID
  448. };
  449. SetOAuthContextCookie(ctx);
  450. var oauth2 = new OAuth2Client(GetProviderTypeFromOAuthProfileTypes(ip.ProviderType.Value), ip.ClientID, ip.ClientSecret);
  451. switch (ip.ProviderType)
  452. {
  453. case OAuth2ProviderTypes.Google:
  454. return new OAuth2ActionResult(oauth2, ProviderType.Google, null);
  455. case OAuth2ProviderTypes.Facebook:
  456. return new OAuth2ActionResult(oauth2, ProviderType.Facebook, null);
  457. case OAuth2ProviderTypes.Live:
  458. return new OAuth2ActionResult(oauth2, ProviderType.Live, null);
  459. }
  460. return View("Error");
  461. }
  462. ProviderType GetProviderTypeFromOAuthProfileTypes(OAuth2ProviderTypes type)
  463. {
  464. switch (type)
  465. {
  466. case OAuth2ProviderTypes.Facebook: return ProviderType.Facebook;
  467. case OAuth2ProviderTypes.Live: return ProviderType.Live;
  468. case OAuth2ProviderTypes.Google: return ProviderType.Google;
  469. default: throw new Exception("Invalid OAuthProfileTypes");
  470. }
  471. }
  472. [HttpGet]
  473. public async Task<ActionResult> OAuthTokenCallback()
  474. {
  475. var ctx = GetOAuthContextCookie();
  476. var ip = GetVisibleIdentityProviders().Single(x => x.ID == ctx.IdP);
  477. var oauth2 = new OAuth2Client(GetProviderTypeFromOAuthProfileTypes(ip.ProviderType.Value), ip.ClientID, ip.ClientSecret);
  478. var result = await oauth2.ProcessCallbackAsync();
  479. if (result.Error != null) return View("Error");
  480. var claims = result.Claims.ToList();
  481. string[] claimsToRemove = new string[]
  482. {
  483. "http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider",
  484. ClaimTypes.AuthenticationInstant
  485. };
  486. foreach (var toRemove in claimsToRemove)
  487. {
  488. var tmp = claims.Find(x => x.Type == toRemove);
  489. if (tmp != null) claims.Remove(tmp);
  490. }
  491. claims.Add(new Claim(Constants.Claims.IdentityProvider, ip.Name, ClaimValueTypes.String, Constants.InternalIssuer));
  492. var id = new ClaimsIdentity(claims, "OAuth");
  493. var cp = new ClaimsPrincipal(id);
  494. return ProcessOAuthResponse(cp, ctx);
  495. }
  496. private ActionResult ProcessOAuthResponse(ClaimsPrincipal principal, Context context)
  497. {
  498. var message = new SignInRequestMessage(new Uri("http://foo"), context.Realm);
  499. message.Context = context.Wctx;
  500. // issue token and create ws-fed response
  501. var wsFedResponse = FederatedPassiveSecurityTokenServiceOperations.ProcessSignInRequest(
  502. message,
  503. principal,
  504. TokenServiceConfiguration.Current.CreateSecurityTokenService());
  505. // set cookie for single-sign-out
  506. new SignInSessionsManager(HttpContext, _cookieName, ConfigurationRepository.Global.MaximumTokenLifetime)
  507. .SetEndpoint(context.WsFedEndpoint);
  508. return new WSFederationResult(wsFedResponse, requireSsl: ConfigurationRepository.WSFederation.RequireSslForReplyTo);
  509. }
  510. #endregion
  511. }
  512. }