Can OAuth2 and session-based authentication coexist in Spring Security?
I have a web application that uses spring security for session connections using username and password authentication with the following security application xml context.
<global-method-security pre-post-annotations="enabled" />
<http pattern="/css/**" security="none" />
<http pattern="/files/**" security="none" />
<http auto-config='true' entry-point-ref="authenticationEntryPoint" access-decision-manager-ref="accessDecisionManager">
<intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY" method="OPTIONS" />
<intercept-url pattern="/login/*" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/login" access="IS_AUTHENTICATED_ANONYMOUSLY" />
<intercept-url pattern="/**" access="REGISTERED" />
<form-login login-page="/login" login-processing-url="/login_security_check" authentication-failure-handler-ref="xxxAuthenticationFailureHandler" authentication-success-handler-ref="xxxAuthenticationSuccessHandler" />
<logout invalidate-session="true" logout-url="/data/logout" success-handler-ref="xxxLogoutSuccessHandler" />
<remember-me key="xxxRem" />
</http>
<beans:bean id="accessDecisionManager" class="org.springframework.security.access.vote.AffirmativeBased">
<beans:property name="decisionVoters">
<beans:list>
<beans:ref bean="roleVoter" />
<beans:ref bean="authenticatedVoter" />
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="roleVoter" class="org.springframework.security.access.vote.RoleVoter">
<beans:property name="rolePrefix" value="" />
</beans:bean>
<beans:bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter">
</beans:bean>
<beans:bean id="userDetailsService" class="com.xxx.web.security.XXXUserDetailsService">
</beans:bean>
<authentication-manager alias="authenticationManager">
<authentication-provider user-service-ref='userDetailsService'>
<password-encoder hash="md5">
<salt-source user-property="username" />
</password-encoder>
</authentication-provider>
</authentication-manager>
<beans:bean id="loginUrlAuthenticationEntryPoint" class="org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint">
<beans:constructor-arg value="/login" />
</beans:bean>
<beans:bean id="authenticationEntryPoint" class="org.springframework.security.web.authentication.DelegatingAuthenticationEntryPoint">
<beans:property name="defaultEntryPoint" ref="loginUrlAuthenticationEntryPoint" />
</beans:bean>
Now I want to expose my web services to a mobile app, so I am looking for an OAuth2 implementation. I have read the examples provided on github.
I was wondering how these two security threads can coexist since the url interception pattern will be the same for both threads?
You will need to change the rules access=""
for the resources that are shared with the UI and OAuth resources. This is not very common for someone who really crosses a lot, but I guess for simple applications this is possible thanks to content alignment. Probably the easiest is to use the SpEL support in XML (or switch to Java config). Example:
<intercept-url pattern="/** access="isFullyAuthenticated() or #oauth2.hasScope('read')"/>
For an alternative approach, you can create aliases for your endpoints and protect them with separate filter chains, one for token and one for cookie-based authentication. Example:
@RequestMapping({ "/user", "/api/user" })
public Map<String, String> user(Principal principal) {
Map<String, String> map = new LinkedHashMap<>();
map.put("name", principal.getName());
return map;
}
where "/ user" is protected as a regular resource (ie with WebSecurityConfigurerAdapter
in Java config) and “/ api / user” is configured separately (ie with ResourceServerConfigurerAdapter
in Java config).