Accept facebook login into my REST API - facebook

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.

Related

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

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.

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.

Spring Security multiple filter chain issue

We have a functioning application with multiple filter chain configuration. One of the first filter chains belongs to REST POST requests that requier no authentication:
...
<http pattern="/*.info**" entry-point-ref="infoEntryPoint" use-expressions="true" create-session="never">
<intercept-url pattern="/*.info" access="permitAll" />
</http>
<beans:bean id="infoEntryPoint" class="org.springframework.security.web.authentication.www.BasicAuthenticationEntryPoint">
<beans:property name="realmName" value="Info REST Realm" />
</beans:bean>...
It worked for GET and POST requests, but after upgrading to Spring Security 4, the POST requests are not captured by this filter chain, but the next filter chain captures them (and creates session and throws 403, doing right its job).
How could I fix it?
CSRF protection is switched on by default in Spring Security, it was switched off by default formerly. The following entry (inside the http tag) solved the problem:
<csrf disabled="true"/>

Create logon token using BI Platform RESTful SDK

I'm attempting to create a logon token using the BOE BI Platform RESTful SDK v4.1 (using RESTClient).
A GET request to http://server:6405/biprws/logon/long/ returns:
<attrs xmlns="http://www.sap.com/rws/bip">
<attr name="userName" type="string" />
<attr name="password" type="string" />
<attr name="auth" type="string" possibilities="secEnterprise,secLDAP,secWinAD,secSAPR3">secEnterprise</attr>
</attrs>
A POST to http://server:6405/biprws/logon/long/ with a single header of Content-Type: application/xml and a payload of
<attrs xmlns="http://www.sap.com/rws/bip">
<attr name="userName" type="string">myAccount</attr>
<attr name="password" type="string">myPassword</attr>
<attr name="auth" type="string" possibilities="secEnterprise,secLDAP,secWinAD,secSAPR3">secWinAD</attr>
</attrs>
returns:
<error>
<error_code>FWM 00006</error_code>
<message>Active Directory Authentication failed to log you on. Please contact your system administrator to make sure you are a member of a valid mapped group and try again. If you are not a member of the default domain, enter your user name as UserName#DNS_DomainName, and then try again. (FWM 00006)</message>
</error>
I've also tried attr name="userName" type="string">myAccount#mycompany.org</attr>, but with the same results.
A POST to http://server:6405/biprws/logon/adsso returns:
<error>
<error_code>RWS 00057</error_code>
<message>Method not allowed (RWS 00057)</message>
</error>
The credentials work with BI Launchpad and the CMC.
What am I missing?
First, a disclaimer -- I've only done REST WinAD with SSO, not manual logon. So I can't be absolutely sure that my suggestions below will fix your problem.
The call to /biprws/logon/adsso requires a GET not a POST, but that will likely not work until you have SSO working.
There are a few settings that are required for WACS to use WinAD, with or without SSO. The file is here:
SAP BusinessObjects\SAP BusinessObjects Enterprise XI 4.0\java\pjs\services\RestWebService\biprws\WEB-INF\web.xml
You will see a section commented out, starting with:
<!-- Kerberos filter section starts
Uncomment this section. Then set the following parameters:
idm.realm
idm.princ
idm.keytab
idm.kdc
idm.allowUnsecured
The values for these parameters should equal what was set in your system for BI launch pad. This is in:
SAP BusinessObjects\tomcat\webapps\BOE\WEB-INF\config\custom\global.properties
The format of the file is different (global.properties is a simple properties file, but web.xml is xml). So you can't just copy/paste the section, but you can copy the individual values. For example, in global.properties, you might see:
idm.keytab=C:/WINDOWS/bosso.keytab
This would be done in web.xml as:
<init-param>
<param-name>idm.keytab</param-name>
<param-value>C:/WINDOWS/bosso.keytab</param-value>
<description>
The file containing the keytab that Kerberos will use for
user-to-service authentication. If unspecified, SSO will default
to using an in-memory keytab with a password specified in the
com.wedgetail.idm.sso.password environment variable.
</description>
</init-param>
Couple of references:
http://myinsightbi.blogspot.com/
https://techwriter79.wikispaces.com/file/view/sbo41sp5_bip_rest_ws_en.pdf

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.