Esempio n. 1
0
        public async Task <SignInResponse> GenerateSignInResponse(SignInRequest request)
        {
            if (request == null)
            {
                throw new ArgumentNullException(nameof(request));
            }

            _logger.LogDebug("Creating signin response");

            var rp = await _relyingPartyStore.GetByRealm(request.Realm);

            // create profile
            _logger.LogDebug("Calling user profile manager");
            var outgoingSubject = await CreateUserProfileAsync(request);

            _logger.LogDebug("Creating security token");
            // create token for user
            var token = await CreateSecurityTokenAsync(request, rp, outgoingSubject);

            var response = new SignInResponse
            {
                AppliesTo = request.Realm,
                Token     = token
            };

            return(response);
        }
Esempio n. 2
0
        public async Task Invoke(HttpContext context)
        {
            var segment = _options.WsFedEndpoint;

            if (context.Request.Path.StartsWithSegments(new PathString(segment), StringComparison.InvariantCultureIgnoreCase))
            {
                _logger.LogInformation("Received WsFed Request. {0}", context.Request.QueryString.ToUriComponent());

                if (!context.User.Identity.IsAuthenticated)
                {
                    _logger.LogInformation("User is not authenticated. Redirecting to authentication provider");

                    var qs  = context.Request.QueryString;
                    var url = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.PathBase}{segment}/{context.Request.QueryString}";

                    await context.ChallengeAsync(new AuthenticationProperties
                    {
                        RedirectUri = url
                    });

                    return;
                }

                var message = WsFederationMessage.FromQueryString(context.Request.QueryString.ToUriComponent());

                if (message.IsSignInMessage)
                {
                    var relyingParty = await _relyingPartyStore.GetByRealm(message.Wtrealm);

                    if (relyingParty == null)
                    {
                        _logger.LogWarning("No relying party found for realm {0}", message.Wtrealm);

                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        await context.Response.WriteAsync($"The realm { message.Wtrealm} is not registered");
                    }

                    _logger.LogWarning("Processing WsFed Sign In for realm {0}", message.Wtrealm);

                    var output = await HandleSignIn(message, context, relyingParty.ReplyUrl);

                    context.Response.ContentType = "text/html";
                    await context.Response.WriteAsync(output);

                    return;
                }
                else if (message.IsSignOutMessage)
                {
                    _logger.LogWarning("Processing WsFed Sign Out");

                    var output = await HandleSignOut(message, context);

                    context.Response.ContentType = "text/html";
                    await context.Response.WriteAsync(output);

                    return;
                }

                context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                await context.Response.WriteAsync($"Invalid Ws-Fed Request Message");

                return;
            }

            await _next(context);
        }
Esempio n. 3
0
        public async Task Invoke(HttpContext context)
        {
            var segment             = _options.Saml20Endpoint;
            var idpInitiatedSegment = $"{segment}/idpinitiated";

            if (context.Request.Path.StartsWithSegments(new PathString(segment), StringComparison.InvariantCultureIgnoreCase))
            {
                if (!(
                        context.Request.Method.Equals("POST", StringComparison.InvariantCultureIgnoreCase) ||
                        context.Request.Method.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
                    )
                {
                    context.Response.StatusCode = (int)HttpStatusCode.MethodNotAllowed;

                    return;
                }

                _logger.LogInformation("Received SAML 2.0 Request. {0}", context.Request.QueryString.ToUriComponent());

                if (context.Request.Path.StartsWithSegments(idpInitiatedSegment))
                {
                    if (!context.Request.Query.ContainsKey("realm"))
                    {
                        _logger.LogWarning("Invalid message. IDP Initiated with no realm");

                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        await context.Response.WriteAsync($"Invalid message. IDP Initiated with no realm");

                        return;
                    }
                }
                else if ((context.Request.Method == "GET" && !context.Request.Query.ContainsKey("SAMLRequest")) ||
                         (context.Request.Method == "POST" && !context.Request.Form.ContainsKey("SAMLRequest")))
                {
                    _logger.LogWarning("Invalid message. It does not contain SAMLRequest");

                    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    await context.Response.WriteAsync($"Invalid SAMLRequest Request Message");

                    return;
                }

                SamlRequestMessage message = null;

                if (context.Request.Path.StartsWithSegments(idpInitiatedSegment))
                {
                    message = new SamlRequestMessage(
                        Guid.NewGuid().ToString(),
                        context.Request.Query["realm"],
                        context.Request.Query["relayState"],
                        true);
                }
                else
                {
                    if (context.Request.Method.Equals("GET", StringComparison.InvariantCultureIgnoreCase))
                    {
                        var samlRequest = context.Request.Query["SAMLRequest"];

                        _logger.LogWarning("Processing SAMLRequest from GET");

                        message = SamlRequestMessage.CreateFromCompressedRequest(samlRequest, context.Request.Query["relayState"]);
                    }
                    else
                    {
                        var samlRequest = context.Request.Form["SAMLRequest"];

                        _logger.LogWarning("Processing SAMLRequest from POST");

                        message = SamlRequestMessage.CreateFromEncodedRequest(samlRequest, context.Request.Form["relayState"]);
                    }
                }

                if (!context.User.Identity.IsAuthenticated)
                {
                    _logger.LogInformation("User is not authenticated. Redirecting to authentication provider");

                    var qs  = context.Request.QueryString;
                    var url = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.PathBase}{idpInitiatedSegment}/?realm={message.Issuer}&relayState={message.RelayState}";

                    await context.ChallengeAsync(new AuthenticationProperties
                    {
                        RedirectUri = url
                    });

                    return;
                }

                var relyingParty = await _relyingPartyStore.GetByRealm(message.Issuer);

                if (relyingParty == null)
                {
                    _logger.LogWarning("No relying party found for realm {0}", message.Issuer);

                    context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    await context.Response.WriteAsync($"{message.Issuer} is not registered");

                    return;
                }

                var parameters = context.Request.Query.ToDictionary(q => q.Key, q => q.Value[0]);

                if (message.IsSignInMessage)
                {
                    _logger.LogWarning("Processing SAML Sign In for relying party with realm {0}", message.Issuer);

                    var output = await HandleSignIn(context,
                                                    message,
                                                    _options.IssuerName,
                                                    parameters,
                                                    relyingParty.ReplyUrl);

                    context.Response.ContentType = "text/html";
                    await context.Response.WriteAsync(output);

                    return;
                }
                else
                {
                    _logger.LogWarning("Processing SAML Sign out for relying party with realm {0}", message.Issuer);

                    var output = HandleSignOut(context, message,
                                               _options.IssuerName,
                                               parameters,
                                               relyingParty.LogoutUrl);

                    context.Response.ContentType = "text/html";
                    await context.Response.WriteAsync(output);

                    return;
                }
            }

            await _next(context);
        }