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.
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}
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With