Developing an application which requires REST authentication as well as form login. Currently spring security oauth 2 with ajax login works. In subsequent request could send 'Authorization Bearer ' and server successfully authorizes the request.
Ajax code for login/signin
function signIn() {
$.ajax({
type : 'POST',
url : 'oauth/token',
data : {
'client_id' : 'XXXXX',
'client_secret' : 'YYYYYY',
'grant_type' : 'password',
'username' :encodeURIComponent($('#login').val()),
'password' : encodeURIComponent($('#password').val()),
'scope' : 'read write'
},
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", "Basic " + $.base64.encode("XXXXX" + ':' + "YYYYYY") )
},
success : function(response) {
var expiredAt = new Date();
expiredAt.setSeconds(expiredAt.getSeconds() + response.expires_in);
response.expires_at = expiredAt.getTime();
localStorage.setItem('ls.token', JSON.stringify(response));
$.cookie("Authorization", "Bearer " + JSON.parse(localStorage.getItem("ls.token")).access_token );
var link = /*[[@{/}]]*/;
$(location).attr('href',link);
}
});
}
In subsequent AJAX requests authorization is included as
$.ajax({
url: 'api/ZZZZZ/',
type: 'GET',
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", "Bearer " + JSON.parse(localStorage.getItem("ls.token")).access_token )
},
success: function(data) {}
I could see the authorization bearer in request header while making AJAX call
Accept */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Authorization Bearer 49ef5d34-88a2-4e20-bd7a-87042c6a62b4
Cache-Control max-age=0
Connection keep-alive
Host localhost:8080
Referer http://localhost:8080/productview?productId=19
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:42.0) Gecko/20100101 Firefox/42.0
X-Requested-With XMLHttpRequest
My spring security configuration looks like
package com.geekyworks.equip.wowperks.config;
import javax.inject.Inject;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.data.repository.query.SecurityEvaluationContextExtension;
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Inject
private UserDetailsService userDetailsService;
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Inject
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.userDetailsService(userDetailsService)
.passwordEncoder(passwordEncoder());
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring()
.antMatchers("/scripts/**/*.{js,html}")
.antMatchers("/bower_components/**")
.antMatchers("/i18n/**")
.antMatchers("/assets/**")
.antMatchers("/swagger-ui/index.html")
.antMatchers("/api/register")
.antMatchers("/api/activate")
.antMatchers("/api/account/reset_password/init")
.antMatchers("/api/account/reset_password/finish")
.antMatchers("/api/home/**")
.antMatchers("/api/product/**")
.antMatchers("/test/**")
.antMatchers("/devadmin/**")
.antMatchers("/signin")
.antMatchers("/static/api-guide.html");
}
@Order(67) // LOWEST
@Configuration
public static class NoAuthConfigurationAdapter extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.antMatcher("/**")
.authorizeRequests()
.anyRequest()
.permitAll();
}
}
@Override
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
@Bean
public SecurityEvaluationContextExtension securityEvaluationContextExtension() {
return new SecurityEvaluationContextExtension();
}
}
For all normal http request I'm always getting the spring user as 'anonymousUser' even after login.
Normal http request header (non AJAX) does not include Authorization bearer in request header
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Cache-Control max-age=0
Connection keep-alive
Cookie Authorization=Bearer%2049ef5d34-88a2-4e20-bd7a-87042c6a62b4
Host localhost:8080
Referer http://localhost:8080/
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.11; rv:42.0) Gecko/20100101 Firefox/42.0
Instead it contains authorization bearer as Cookie information. I added cookie information post AJAX login.
Any idea how can I make FORM and AJAX authentication to work simultaneously using spring security oauth in single application?
The way spring security manages form based authentication is totaly different what you are trying to achive through oauth2.0. When you are using ajax (oauth2.0) way of authenticating (which is actualy authorization process of client application by user with username and password) user, only your client application (application through which you are firing ajax request) will get authenticated through spring security filter and SecurityContextHolder will have authentication object of authenticated client application not the user. If you will see your security configuration you are allowing all the request to pass without authentication in case of non ajax login. To enable form based login you need to configure your security to protect all other url except login url... something as given below
@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable().authorizeRequests()
.antMatchers("/**")
.authenticated().and().formLogin();
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.