I am implementing SP-initiated login for SAML authentication(with sustainsys saml library) with owin pipeline. I am facing an issue with receiving the saml response on the configured acs url. The saml response is received from IDP and user is successfully logged in, but when i try to read the saml response at the ACS url endpoint, that method is never hit in the debug flow.
I believe ACS endpoint is where the saml response will be sent back from idp(idp-browser and browser-acs endpoint), can someone point at the issue why saml response is received on the browser but not redirected to ACS URL.
Configured the ACS url on IDP and SP side.
i can see the correct ACS url in Saml request.
Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Verbose: 0 : Signature validation passed for Saml Response Microsoft.IdentityModel.Tokens.Saml2.Saml2Id
Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Verbose: 0 : Extracted SAML assertion <--Assertion_id-->
Sustainsys.Saml2.Owin.Saml2AuthenticationMiddleware Information: 0 : Successfully processed SAML response Microsoft.IdentityModel.Tokens.Saml2.Saml2Id and authenticated <--User-->
Application Insights Telemetry (unconfigured): ":,"ai.location.ip":"::1","ai.internal.sdkVersion"},"data":{"baseType":"RequestData","baseData":{"ver":2,"id":"|/WNNPHCMHVk=.56095c49_","name":"POST <--ACS URL- BASE URL-->","duration":"00:00:00.2807934","success":true,"responseCode":"303","url":"<--ACS URL-->","properties":{"DeveloperMode":"true","_MS.ProcessedByMetricExtractors":"(Name:'Requests', Ver:'1.0')"}}}}
The ACS endpoint is implemented by the library. And as seen in your log, it is done successfully.
Then the library issues a login using the configured login scheme, which is normally the external cookie scheme (but can also be the application cookie scheme). It's probably something there that's not correctly configured in your code.
I have set up the authentication type to ExternalCookie, it still doesn't reach my acs url with the saml response. POST request to acs url is returning with a 303 status code
In Startup
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
CookieSecure = CookieSecureOption.Always,
ExpireTimeSpan = TimeSpan.FromMinutes(30),
LoginPath = new PathString("/Account/SignIn"),
SlidingExpiration = true,
});
app.SetDefaultSignInAsAuthenticationType(DefaultAuthenticationTypes.ExternalCookie);
app.UseSaml2Authentication(CreateSaml2Options());
public ActionResult ExternalLogin(string provider, string rURL, string uname)
{
return new ChallengeResult(provider,
Url.Action("ExternalLoginCallback",
"Account"), uname);
}
ACS ENDPOINT
[HttpPost]
public ActionResult Acs(string username, string samlResponse)
{
......
}
It will be very helpful if anyone can provide some input on this.
Related
I have a client application which authenticates with facebook and returns the token successfully. I would like to persist this data to the server without having to pass the entire object. Instead I would like to pass the resulting token from the client side authentication to my C# api in the authorization header and validate this token on the server.
Question, is it possible to verify the token on the server side? How to do it?
I am doing this via google, and need a facebook equivalent:
var googleResult = GoogleJsonWebSignature.ValidateAsync(
accessToken,
new GoogleJsonWebSignature.ValidationSettings
{
Audience = new[] { "secret key here.apps.googleusercontent.com" }
}
).GetAwaiter().GetResult();
I've created a facebook app on facebook developers
I've setup a local rails server and exposed it to public internet using ngrok. I'm receiving facebook's webhook validation GET request and I'm returning the hub_challenge code in response. The response status code is also 200. I've provided a secret Verify Token which is required to set up a messenger webhook. But after all this I'm getting error
The Callback URL or Verify Token couldn't be validated. Please verify
the provided information or try again later.
I've checked that the request is received and the response being sent back to the facebook server, but don't know why it fails and says Verify Token couldn't be validated. Is it some special token that I have to get from somewhere from facebook messenger platform? Currently I've provided it my own secret token. Any help will be appreciated. Thanks
when I verify Facebook Webhook with my website i got that kind error
The URL couldn't be validated. Response does not match challenge, expected value="1421256154", received="1421256154\u003Clink rel=..."
My code
public function verify_token(Request $request)
{
$mode = $request->get('hub_mode');
$token = $request->get('hub_verify_token');
$challenge = $request->get('hub_challenge');
if ($mode === "subscribe" && $this->token and $token === $this->token) {
return response($challenge,200);
}
return response("Invalid token!", 400);
}
my code everything is ok .I am using laravel thats why APP_DEBUG=true defalt when I change it APP_DEBUG=false its working and my problem solved.
I have installed an IdentityServer4 and a Client (Hybrid Mvc Client). All is ok. The following flow works:
1. User call secure page PageX (the controller is protected with Authorize attribute)
2. than system redirects the flow to Login page on IdentityServer
3. After authentication/authorization the IdentityServer redirect the user to url defined (redirect_uri) in the client configuration (page named Home) .
Now i don't know how to implement at the step 3 the redirection to PageX, the original page requested.
I have to create a custom AuthorizeAttribute to save on session storage the url of PageX and than using it in callback page? or is there any configuration on IdentityServer or client that could help me?
Thanks in advance
This is typically what you’d use the state parameter for. Your callback will receive the state value back unaltered and then you can verify the URL within is local and redirect to it automatically.
I’d recommend protecting the value from tampering using the DataProtection features in .net.
After successful login, by default the IdentityServer middleware tries to redirect to a consent page where to inform the user for the "allowed scopes". In this page are shown the claims that the client mvc site will receive access to: user identifier, user profile, email etc.
If you didn't setup such, you may set: "RequireConsent = false" when you define your MVC client. In such scenario the IdentityServer will redirect back to "RedirectUris" without showing consent page.
Example:
public static IEnumerable<Client> GetClients()
{
return new List<Client>
{
new Client
{
ClientId = "mvc",
ClientName = "mvc Client",
ClientSecrets =
{
new Secret("secret".Sha256())
},
AllowedGrantTypes = GrantTypes.Implicit,
AllowAccessTokensViaBrowser = true,
RedirectUris = { "http://localhost:5002/signin-oidc" },
PostLogoutRedirectUris = { "http://localhost:5002/signout-callback-oidc" },
AllowedScopes =
{
IdentityServerConstants.StandardScopes.OpenId,
IdentityServerConstants.StandardScopes.Profile,
IdentityServerConstants.StandardScopes.Email
},
RequireConsent = false
}
};
}
The other thing that I've noticed in the IdentityServer4 demos and quick starts is that you need the following NuGet packages:
For client website:
IdentityModel,
Microsoft.AspNetCore.All
For IdentityServer Authentication app:
IdentityServer4,
IdentityServer4.AccessTokenValidation,
IdentityServer4.AspNetIdentity,
Microsoft.AspNetCore.All
You may install these packages just to get the demo working.
I have implemented SSO using ADFS3. I have logout button for sign out and it’s working fine with my ws-federation passive endpoints . In logout I redirect user to logout.aspx page and there I have written code on page load as
WSFederationAuthenticationModule authModule = FederatedAuthentication.WSFederationAuthenticationModule;
SignOutRequestMessage signOutRequestMessage = new SignOutRequestMessage(new Uri(authModule.Issuer), authModule.Realm);
String queryString = signOutRequestMessage.WriteQueryString();
Response.Redirect(queryString);
One of the application uses SAML so I have created SAML assertion consumer end point. So when I open this application and hit logout it throws error and when I see event log on ADFS
Encountered error during federation passive request.
Additional Data
Protocol Name:
wsfed
Relying Party:
Exception details:
Microsoft.IdentityServer.RequestFailedException: MSIS7055: Not all SAML session participants logged out properly. It is recommended to close your browser.
at Microsoft.IdentityServer.Web.Protocols.Saml.SamlProtocolHandler.BuildSamlLogoutResponse(SamlContext samlContext, Boolean partialLogout, Boolean& logoutComplete)
at Microsoft.IdentityServer.Web.Protocols.Saml.SamlProtocolHandler.ProcessSignOut(SamlContext samlContext, String redirectUri, List`1 iFrameUris, Boolean partialLogout)
at Microsoft.IdentityServer.Web.Protocols.Saml.SamlProtocolHandler.PipelineInitiatedSignout(WrappedHttpListenerContext httpContext, String redirectUri)
at Microsoft.IdentityServer.Web.PassiveProtocolListener.ProcessProtocolSignoutRequest(ProtocolContext protocolContext, PassiveProtocolHandler protocolHandler)
at Microsoft.IdentityServer.Web.PassiveProtocolListener.ProcessProtocolRequest(ProtocolContext protocolContext, PassiveProtocolHandler protocolHandler)
at Microsoft.IdentityServer.Web.PassiveProtocolListener.OnGetContext(WrappedHttpListenerContext context)
MSDN explicitly says it should do 401 redirect, but I'm getting a 302 redirect on FF, and this is causing problems in AJAX requests as the returned status is 200 (from the redirected page).
http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizeattribute.aspx
I've found someone else with the same problem:
http://blog.nvise.com/?p=26
Any other solution, besides his?
I really like this solution. By changing the 302 response on ajax requests to a 401 it allows you to setup your ajax on the client side to monitor any ajax request looking for a 401 and if it finds one to redirect to the login page. Very simple and effective.
Global.asax:
protected void Application_EndRequest()
{
if (Context.Response.StatusCode == 302 &&
Context.Request.Headers["X-Requested-With"] == "XMLHttpRequest")
{
Context.Response.Clear();
Context.Response.StatusCode = 401;
}
}
Client Side Code:
$(function () {
$.ajaxSetup({
statusCode: {
401: function () {
location.href = '/Logon.aspx?ReturnUrl=' + location.pathname;
}
}
});
});
The Authorize attribute does return a Http 401 Unauthorized response. Unfortunately, however if you have FormsAuthentication enabled, the 401 is intercepted by the FormsAuthenticationModule which then performs a redirect to the login page - which then returns a Http 200 (and the login page) back to your ajax request.
The best alternative is to write your own authorization attribute, and then if you get an unauthenticated request that is also an Ajax request, return a different Http status code - say 403 - which is not caught by the formsAuthenticationModule and you can catch in your Ajax method.
I implemented my own custom authorize attribute which inherited from AuthorizeAttribute and ran into the same problem.
Then I found out that since .Net 4.5 there is a solution to this - you can suppress the redirect in the following way:
context.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
Then the response will be a 401 - Unauthorized, along with the HTTP Basic authentication challenge.
More info here
If you are using a ASP.NET MVC 5 Web Application go to App_Start -> Startup.Auth.cs. Check if app.UseCookieAuthentication is enabled and see if CookieAuthenticationOptions is set to LoginPath = new PathString("/Login"), or similar. If you remove this parameter 401 will stop redirecting.
Description for LoginPath:
The LoginPath property informs the middleware that it should change an
outgoing 401 Unauthorized status code into a 302 redirection onto the
given login path. The current url which generated the 401 is added to
the LoginPath as a query string parameter named by the
ReturnUrlParameter. Once a request to the LoginPath grants a new
SignIn identity, the ReturnUrlParameter value is used to redirect the
browser back to the url which caused the original unauthorized status
code. If the LoginPath is null or empty, the middleware will not look
for 401 Unauthorized status codes, and it will not redirect
automatically when a login occurs.