How do I hook into IDP initiated single logout to run custom code? - sustainsys-saml2

I'm using sustainsys.saml2.httpmodule. I would like to run some code to log the logout from an IDP initiated single log out. The user also does not seem to be logged out (IsAuthenticated is still true) after an IDP initiated single log out even though https://stubidp.sustainsys.com/Logout gives me a success result.
I can't seem to find anyone else needing the same functionality or having the same issues. My Sustainsys config is below.
<sustainsys.saml2 entityId="http://localhost:53758/Saml2"
returnUrl="http://localhost:53758/Common/Pages/Saml2Login.aspx"
authenticateRequestSigningBehavior="IfIdpWantAuthnRequestsSigned"
validateCertificates="false"
publicOrigin ="http://localhost:53758/">
<nameIdPolicy allowCreate="false" format="Unspecified"/>
<metadata cacheDuration="PT1440M" wantAssertionsSigned="true">
<organization name="ab" displayName="ab" url="https://www.example.com/" language="en" />
<contactPerson type="Technical" email="a#b.com" />
<requestedAttributes>
<add friendlyName ="Some Name" name="urn:someName" nameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" isRequired="true" />
</requestedAttributes>
</metadata>
<identityProviders>
<add entityId="https://stubidp.sustainsys.com/Metadata"
signOnUrl="https://stubidp.sustainsys.com"
logoutUrl="https://stubidp.sustainsys.com/Logout"
allowUnsolicitedAuthnResponse="true"
binding="HttpRedirect"
wantAuthnRequestsSigned="true">
<signingCertificate storeName="CertificateAuthority" storeLocation="CurrentUser"
findValue="cdf7090a433561a843b51198b0ba6456" x509FindType="FindBySerialNumber" />
</add>
</identityProviders>
<serviceCertificates>
<add storeName="CertificateAuthority" storeLocation="CurrentUser" findValue="2cfe21cb930c19a341e9e30a07a3c123" x509FindType="FindBySerialNumber" />
</serviceCertificates>
</sustainsys.saml2>

You can use the LogoutCommandResultCreated notification. It will get called both when the redirect to the Idp is about to happen as well as after the response has been received from the Idp.

Related

Shibboleth integration

currently We have CAS SSO to our existing .net application, but now client is asking for Shibboleth SSO instead CAS. I'm totally new to Shibboleth.
Client has given the below details:
entityid= urn:mace:incommon:xxx.edu
metadata URL for test environment is:
https://shibboleth-test.xxx.edu/idp/shibboleth
By using guidelines from Shibboleth site, below are the steps i followed.
Installed Shibbolth Service provider (shibboleth-sp-2.6.1.4-win64.msi)
Installed Java with JCE
Installed Shibboleth Idp (in which jetty also checked)(shibboleth-identity-provider-3.3.3-x64.msi)
Web Application with self signed certificate
attached my Shibboleth2.xml file
<SPConfig xmlns="urn:mace:shibboleth:2.0:native:sp:config" xmlns:conf="urn:mace:shibboleth:2.0:native:sp:config" xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata" clockSkew="180"> <InProcess logger="native.logger"> <ISAPI normalizeRequest="true" safeHeaderNames="true">
<Site id="2" name="shibboleth-test.xxx.edu" scheme="https" port="443" />
</ISAPI> </InProcess> <RequestMapper type="Native"> <RequestMap> <Host name="shibboleth-test.xxx.edu" scheme="https" port="443">
<Path name="secure" authType="shibboleth" requireSession="true"/>
</Host>
</RequestMap></RequestMapper><ApplicationDefaults entityID="urn:mace:incommon:xxx.edu" REMOTE_USER="eppn persistent-id targeted-id" cipherSuites="ECDHE+AESGCM:ECDHE:!aNULL:!eNULL:!LOW:!EXPORT:!RC4:!SHA:!SSLv2"> <Sessions lifetime="28800" timeout="3600" relayState="ss:mem" checkAddress="false" handlerSSL="true" cookieProps="https"> <SSO entityID=""urn:mace:incommon:xxx.edu" discoveryProtocol="SAMLDS" discoveryURL="https://ds.example.org/DS/WAYF"> SAML2 SAML1 </SSO>
<!-- SAML and local-only logout. -->
<Logout>SAML2 Local</Logout>
<!-- Extension service that generates "approximate" metadata based on SP configuration. -->
<Handler type="MetadataGenerator" Location="/Metadata" signing="false"/>
<!-- Status reporting service. -->
<Handler type="Status" Location="/Status" acl="127.0.0.1 ::1 <my system IP">/>
<!-- Session diagnostic service. -->
<Handler type="Session" Location="/Session" showAttributeValues="false"/>
<!-- JSON feed of discovery information. -->
<Handler type="DiscoveryFeed" Location="/DiscoFeed"/>
</Sessions>
<Errors supportContact="root#localhost"
helpLocation="/about.html" styleSheet="/shibboleth-sp/main.css"/> <!-- Map to extract attributes from SAML assertions. --> <AttributeExtractor type="XML" validate="true" reloadChanges="false" path="attribute-map.xml"/>
<AttributeResolver type="Query" subjectMatch="true"/> <AttributeFilter type="XML" validate="true" path="attribute-policy.xml"/>
<CredentialResolver type="File" key="sp-key.pem" certificate="sp-cert.pem"/>
</ApplicationDefaults>
<SecurityPolicyProvider type="XML" validate="true" path="security-policy.xml"/>
<ProtocolProvider type="XML" validate="true" reloadChanges="false" path="protocols.xml"/>
</SPConfig>
Problems I'm facing......
When i try to access https://shibboleth-test.xxx.edu/Shibboleth.sso/Status
getting error no metadataprovider available.
Noticed Problems:
1.when i try to add Metadataprovider Shibboleth daemon 2 service is getting
stopped and unable to start.if i remove it's is running.
2.Shibboleth Idp 3 deamon is getting stopped very frequently
When i run 'SC interrogate shibd_idp' in command prompt, results are
control service failed 1062
the service has not been started.
I donno what is wrong with my work.
Can any one please tell me what are the steps to be followed to accomplish this integration.
Thanks in advance,
Hema
There will be a tag in shibboleth2.xml called metadata provider, you will need to open that.
If you have done this but shill service is not getting started then you can check the log and give additional info in question.
Another reason I can think of is connection problem. Try downloading idP's metadata and store it physically in the SP configuration folder. Manually map the file, using following tag
<MetadataProvider type="XML" file="partner-metadata.xml"/>
All the issues has been resolved after we upgraded from Shibboleth 2.6 to 3.0.2. we are getting the Shibboleth Identity provider login page.We are able to see the attributes in Session.Now we are working on how to retrieve the attributes in our application and how to redirect to our application home page.Currently we created 1 sample html page under secure folder in our application. once we logged in we are able to this html page.But when i tried to redirect to our application home page, it's giving 500 error. Can any one knows like how to redirect to our app home page and retrieve the attributes in the application.

UseOpenIdConnectAuthentication kills postback

I am trying to include SSO with office 365 for one of our web applications.
the problem is that as soon as SSO is working all my postbacks are getting ignored.
what I did was the following,
I installed those Nuget Packages
- Microsoft.Owin
- Microsoft.Owin.Host.SystemWeb
- Microsoft.Owin.Security
- Microsoft.Owin.Security.Cookies
- Microsoft.Owin.Security.OpenIdConnect
- Owin
I created an app in my AAD
then I've added some settings to my web.config
<add key="ida:PostRedirectUri" value="http://localhost:4439" />
<add key="ida:ClientId" value="XXXXXXX" />
<add key="ida:AADInstance" value="https://login.microsoftonline.com/" />
<add key="ida:Tenant" value="XXXX.onmicrosoft.com" />
<add key="ida:PostLogoutRedirectUri" value="http://localhost:4439" />
and I added Startup.vb to my solution with the following content
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType)
app.UseCookieAuthentication(New CookieAuthenticationOptions())
app.UseOpenIdConnectAuthentication(New OpenIdConnectAuthenticationOptions() With {
.ClientId = clientId,
.Authority = authority
})
app.UseStageMarker(PipelineStage.Authenticate)
and after this the SSO works however al postbacks on buttons fail
if I click a button the page just gets reloaded.
also the IsPostBack parameter is alwayst false.
What I found was that when I remove the "app.UseOpenIdConnectAuthentication" part, postbacks are working again, but SSO is not.
how can I make sure my postbacks are working and I can also use UseOpenIdConnectAuthentication ?
thank you.
I found the issue,
in my web.config I had
<modules runAllManagedModulesForAllRequests="true">
in system.web
removing the key "runAllManagedModulesForAllRequests" solved the problem
<modules>

NWebsec's "A potentially dangerous redirect was detected" with Facebook logon

I have read through NWebSec's documentation to try and resolve the problem.
Set the web.config to
<nwebsec>
<httpHeaderSecurityModule
xsi:noNamespaceSchemaLocation="NWebsecConfig/HttpHeaderSecurityModuleConfig.xsd"
xmlns="http://nwebsec.com/HttpHeaderSecurityModuleConfig.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<redirectValidation enabled="false">
<allowSameHostRedirectsToHttps enabled="false"/>
<add allowedDestination="https://www.facebook.com/"/>
<add allowedDestination="http://www.nwebsec.com/"/>
<add allowedDestination="https://www.google.com/accounts/"/>
</redirectValidation>
<securityHttpHeaders>
<strict-Transport-Security max-age="365" includeSubdomains="true" httpsOnly="false" preload="true" />
</securityHttpHeaders>
</httpHeaderSecurityModule>
but I am still getting
A potentially dangerous redirect was detected. Add the destination to the whitelist in configuration if the redirect was intended. Offending redirect: https://www.facebook.com/dialog/oauth?response_type=code&
This came up in google before the answer, which is here: https://docs.nwebsec.com/en/latest/nwebsec/Redirect-validation.html
In summary you have to whitelist the URL which your login service refers to, like this:
app.UseRedirectValidation(opts =>
{
opts.AllowedDestinations( "https://www.facebook.com/dialog/oauth");
opts.AllowedDestinations("https://login.microsoftonline.com"); // Tested
});

Accept facebook login into my REST API

I have a backend server (Java / Spring / Spring Security).
Currently when users from mobile app login, they simply submit their username/password and Spring Security creates a Session and assign it to the request with a JSESSIONID.
We would now also have a button on the mobile app "Login with Facebook". Here is my understanding of how it will work.
mobile app uses facebook SDK to get an "access_token"
mobile app retrive USer Profile from facebook (name,surname,email etc..)
mobile checks (against MY server) if the username is unique
If username unique, call MY REST api, with something like this /login/facebook POST over SSL and passing the access_token, email, username etc...)
my server then checks if the access_token is valid
GET graph.facebook.com/debug_token?
input_token={token-to-inspect}
&access_token={app-token-or-admin-token}
If yes, if the UID returned by facebook is already present in my local database, I signin the user as follow:
SecurityContextHolder.getContext().setAuthentication(
new UsernamePasswordAuthenticationToken(username, null, ROLE_USER));
If i don't find the UID, I just create a new user and login the user.
and from now on every request made to the server by the mobile will have the SESSION (created and attached by spring security) and the mobile app is authenticated
Could someone tell me if this is a good way of doing things ?
Should I stop using sessions and switch to Spring-Security-OAUTH2 ?
EDIT 1
Based on Dave advices here is the updated spring-security config:
<!- handle login by providing a token-->
<security:http pattern="/login/facebook" auto-config="false" use-expressions="true" entry-point-ref="loginUrlAuthenticationEntryPoint">
<security:custom-filter ref="facebookLoginFilter" position="FORM_LOGIN_FILTER"/>
<security:intercept-url pattern="/**" access="isAuthenticated()" />
</security:http>
<bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<constructor-arg value="/login/facebook"></constructor-arg>
</bean>
<!-- handle basic username + password logins-->
<security:http auto-config="true" use-expressions="true" entry-point-ref="forbiddenEntryPoint">
<security:form-login login-processing-url="/security_check" authentication-failure-handler-ref="authFailureHandler"
default-target-url="/" always-use-default-target="true" authentication-success-handler-ref="authSuccessHandler" />
...
my others patterns..
...
</security:http>
<bean id="forbiddenEntryPoint"
class="org.springframework.security.web.authentication.Http403ForbiddenEntryPoint" />
<bean id="authSuccessHandler" class="my.package.AuthenticationSuccessHandlerImpl"/>
<bean id="authFailureHandler" class="my.package.AuthenticationFailureHandlerImpl"/>
<bean id="facebookLoginFilter" class="pl.jcommerce.ocean.web.ws.controller.FacebookLoginFilter">
<property name="requiresAuthenticationRequestMatcher" ref="loginRequestUrlHandler"></property>
<property name="authenticationManager" ref="authManager"></property>
</bean>
<security:authentication-manager id="authManager">
<security:authentication-provider ref="facebookAuthenticationProvider" />
</security:authentication-manager>
<security:authentication-manager>
<security:authentication-provider ref="webServiceUserAuthenticationProvider" />
</security:authentication-manager>
<bean id="loginRequestUrlHandler" class="org.springframework.security.web.util.matcher.RegexRequestMatcher">
<constructor-arg index="0" value="/login/facebook" />
<constructor-arg index="1" value="POST" />
<constructor-arg index="2" value="false" />
</bean>
Facebook is already using OAuth2 server side, and provides its own native SDK for clients, so I don't see any advantage in your case of using OAuth2 in your server as well, unless your use case extends beyond what you outline above. Spring OAuth2 also has client side support, but not in a native app, so I don't really see anything at all wrong in principle with your proposal. You didn't say in any detail where you would set the security context up in your server, and I think that might be an important detail -- it has to happen in the security filter chain in the right place to get the session to be updated.
I took a crack at implementing something like this based on Dave Syer's answer here along with the Spring Security Angular materials he put together. To see an example see my forked github repo, specifically the classes in the security package.

Spring Security - Login Form - GWT - Anchor tags

I am trying to redirect Spring Security to a custom login page which GWT based. Here is my configuration:
<security:http pattern="/Main.html?#login" security="none" />
<security:http auto-config="true">
<security:form-login login-page='/Main.html?#login' />
<security:intercept-url pattern="/**" access="IS_AUTHENTICATED_FULLY" />
</security:http>
From the spring security debug logs - it seems that the framework drops everything after the "#". Does anyone know how to fix this?
Thanks.
There is no way to fix this. Spring security runs on server side, and data in url after hash are never sent to the server from browser. Normally you would make a separate page for login, outside of your primary GWT application.