Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS spring security login/logout with Cross-Origin Resource Sharing (CORS)

Problem Statement: My UI app is running on 9000 port(grunt project) and my server side spring boot project running on 8421 port. I am able to hit all the URL's from my UI app except login and logout. Please let me know how can I configure spring security login and logout with CORS.

App.js

  $scope.login = function() {
        $http.post('http://localhost:8421/login', $.param($scope.credentials), {
          headers : {
            'content-type' : 'application/x-www-form-urlencoded'
          }
        }).success(function() {
          console.log('login success');
          });
        }).error(function() {
          console.log('login error');
        });
      };

SecurityConfiguration.java

public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

@Override
    protected void configure(HttpSecurity http) throws Exception {

        http.addFilterBefore(new SimpleCORSFilter(), ChannelProcessingFilter.class)
        .authorizeRequests().antMatchers("/rest/**").permitAll()
        .and().logout().logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
        .logoutSuccessUrl("/index.html")        
        .and().exceptionHandling().authenticationEntryPoint(authenticationEntryPoint)       
        .and().formLogin().successHandler(authenticationSuccessHandler)
        .and().formLogin().failureHandler(authenticationFailureHandler)         
        .and().csrf().disable();
    }

@Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService).passwordEncoder(new BCryptPasswordEncoder());
    }
}

SimpleCORSFilter.java

public class SimpleCORSFilter implements Filter {
@Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

        chain.doFilter(req, res);
    }

    @Override
    public void init(FilterConfig filterConfig) {

    }

    @Override
    public void destroy() {

    }
}

login.html

<form>
<div class="rb-form-group" ng-class="{ 'has-error' : userForm.username.$invalid && !userForm.username.$pristine }">
            <input type="text" name="username" class="form-control" ng-model="credentials.username" placeholder="enter your username" required>
        </div>

        <!-- PASSWORD -->
        <div class="rb-form-group" ng-class="{ 'has-error' : userForm.password.$invalid && !userForm.password.$pristine }">
            <input type="password" name="password" class="form-control" ng-model="credentials.password" placeholder="enter your password" required>        
        </div>

        <div class="rb-form-group">
            <button class="btn btn-primary btn-block" ng-disabled="userForm.$invalid" ng-click="login()">Login</button>        
        </div>
</form>

Thanks in advance

Network log

Remote Address:[::1]:8421
Request URL:http://localhost:8421/login
Request Method:POST
Status Code:200 OK
Response Headers
view source
Access-Control-Allow-Credentials:true
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Origin, X-Requested-With, Content-Type, Accept
Access-Control-Allow-Methods:POST, GET, PUT, OPTIONS, DELETE
Access-Control-Allow-Origin:*
Access-Control-Max-Age:3600
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date:Tue, 17 Nov 2015 04:01:57 GMT
Expires:0
Pragma:no-cache
Server:Apache-Coyote/1.1
Set-Cookie:JSESSIONID=D22C05E81D4FC86EA32BD6545F2B37FF; Path=/; HttpOnly
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block
Request Headers
view source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate
Accept-Language:en-US,en;q=0.8
Connection:keep-alive
Content-Length:31
content-type:application/x-www-form-urlencoded
Host:localhost:8421
Origin:http://localhost:9000
Referer:http://localhost:9000/src/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.86 Safari/537.36
like image 497
Pratap A.K Avatar asked Nov 09 '22 01:11

Pratap A.K


1 Answers

As far as CORS issue is concerned, please add authorization and client-security-token to the Access-Control-Allow-Headers header as below.

response.setHeader("Access-Control-Allow-Headers", "x-requested-with, Content-Type, origin, authorization, accept, client-security-token");

This should work properly if your CORS filter is correctly configured!

For using AJAX based login in spring security, you might want to follow slightly different approach. This is explained here:

  • Spring security 3 Ajax login – accessing protected resources
  • Implementing Ajax Authentication

Hope it helps, feel free to comment for any issue!

like image 52
SyntaX Avatar answered Nov 15 '22 05:11

SyntaX