Spring Boot & Security with AngularJS Login page <p>I'm following this tutorial/example of Dave Syer in order to implement a custom AngularJS login page with Spring Security. And the example works fine locally: <a href="https://github.com/dsyer/spring-security-angular/tree/master/single" rel="nofollow">https://github.com/dsyer/spring-security-angular/tree/master/single</a></p> <p>However, when I try to implement this myself, changing some things in a way i would like them to be, I'm not able to authenticate, and I'm not sure where my mistake is. This is the console output where i try to log in:</p> <pre><code>2015-05-04 21:27:18.657 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using Ant [pattern='/**', GET] 2015-05-04 21:27:18.657 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/user' matched by universal pattern '/**' 2015-05-04 21:27:18.657 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/**/favicon.ico']] 2015-05-04 21:27:18.657 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/**/favicon.ico' 2015-05-04 21:27:18.657 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true 2015-05-04 21:27:18.657 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@4c1b0a9b, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]] 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.u.m.MediaTypeRequestMatcher : httpRequestMediaTypes=[application/json, text/plain, */*] 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/json 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/json = true 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = false 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.util.matcher.AndRequestMatcher : Did not match 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.s.HttpSessionRequestCache : Request not saved as configured RequestMatcher did not match 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point. 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. 2015-05-04 21:27:18.658 DEBUG 1260 --- [nio-8080-exec-5] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed 2015-05-04 21:27:23.106 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/css/**' 2015-05-04 21:27:23.107 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/js/**' 2015-05-04 21:27:23.107 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/images/**' 2015-05-04 21:27:23.107 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/**/favicon.ico' 2015-05-04 21:27:23.107 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/error' 2015-05-04 21:27:23.107 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 1 of 11 in additional filter chain; firing Filter: 'WebAsyncManagerIntegrationFilter' 2015-05-04 21:27:23.107 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 2 of 11 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter' 2015-05-04 21:27:23.107 DEBUG 1260 --- [nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : No HttpSession currently exists 2015-05-04 21:27:23.108 DEBUG 1260 --- [nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : No SecurityContext was available from the HttpSession: null. A new one will be created. 2015-05-04 21:27:23.108 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 3 of 11 in additional filter chain; firing Filter: 'HeaderWriterFilter' 2015-05-04 21:27:23.108 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.header.writers.HstsHeaderWriter : Not injecting HSTS header since it did not match the requestMatcher org.springframework.security.web.header.writers.HstsHeaderWriter$SecureRequestMatcher@248a309c 2015-05-04 21:27:23.108 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 4 of 11 in additional filter chain; firing Filter: 'CsrfFilter' 2015-05-04 21:27:23.108 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 5 of 11 in additional filter chain; firing Filter: 'LogoutFilter' 2015-05-04 21:27:23.108 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Request 'GET /user' doesn't match 'POST /logout 2015-05-04 21:27:23.108 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 6 of 11 in additional filter chain; firing Filter: 'RequestCacheAwareFilter' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 7 of 11 in additional filter chain; firing Filter: 'SecurityContextHolderAwareRequestFilter' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 8 of 11 in additional filter chain; firing Filter: 'AnonymousAuthenticationFilter' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.a.AnonymousAuthenticationFilter : Populated SecurityContextHolder with anonymous token: 'org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 9 of 11 in additional filter chain; firing Filter: 'SessionManagementFilter' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.session.SessionManagementFilter : Requested session ID 5140C94E8B1D8BF835A5A52AAA5F4D5B is invalid. 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 10 of 11 in additional filter chain; firing Filter: 'ExceptionTranslationFilter' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.security.web.FilterChainProxy : /user at position 11 of 11 in additional filter chain; firing Filter: 'FilterSecurityInterceptor' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/index.html' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/home.html' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/login.html' 2015-05-04 21:27:23.109 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/' 2015-05-04 21:27:23.110 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor : Secure object: FilterInvocation: URL: /user; Attributes: [authenticated] 2015-05-04 21:27:23.110 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.a.i.FilterSecurityInterceptor : Previously Authenticated: org.springframework.security.authentication.AnonymousAuthenticationToken@9055c2bc: Principal: anonymousUser; Credentials: [PROTECTED]; Authenticated: true; Details: org.springframework.security.web.authentication.WebAuthenticationDetails@b364: RemoteIpAddress: 0:0:0:0:0:0:0:1; SessionId: null; Granted Authorities: ROLE_ANONYMOUS 2015-05-04 21:27:23.110 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.access.vote.AffirmativeBased : Voter: org.springframework.security.web.access.expression.WebExpressionVoter@61c084cb, returned: -1 2015-05-04 21:27:23.110 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point org.springframework.security.access.AccessDeniedException: Access is denied at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:83) at org.springframework.security.access.intercept.AbstractSecurityInterceptor.beforeInvocation(AbstractSecurityInterceptor.java:206) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:115) at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659) at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:745) 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using Ant [pattern='/**', GET] 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Request '/user' matched by universal pattern '/**' 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=Ant [pattern='/**/favicon.ico']] 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.AntPathRequestMatcher : Checking match of request : '/user'; against '/**/favicon.ico' 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = true 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.util.matcher.AndRequestMatcher : Trying to match using NegatedRequestMatcher [requestMatcher=MediaTypeRequestMatcher [contentNegotiationStrategy=org.springframework.web.accept.ContentNegotiationManager@4c1b0a9b, matchingMediaTypes=[application/json], useEquals=false, ignoredMediaTypes=[*/*]]] 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.m.MediaTypeRequestMatcher : httpRequestMediaTypes=[application/json, text/plain, */*] 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.m.MediaTypeRequestMatcher : Processing application/json 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.m.MediaTypeRequestMatcher : application/json .isCompatibleWith application/json = true 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.u.matcher.NegatedRequestMatcher : matches = false 2015-05-04 21:27:23.111 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.util.matcher.AndRequestMatcher : Did not match 2015-05-04 21:27:23.112 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.s.HttpSessionRequestCache : Request not saved as configured RequestMatcher did not match 2015-05-04 21:27:23.112 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.a.ExceptionTranslationFilter : Calling Authentication entry point. 2015-05-04 21:27:23.112 DEBUG 1260 --- [nio-8080-exec-7] o.s.s.w.a.Http403ForbiddenEntryPoint : Pre-authenticated entry point called. Rejecting access 2015-05-04 21:27:23.112 DEBUG 1260 --- [nio-8080-exec-7] w.c.HttpSessionSecurityContextRepository : SecurityContext is empty or contents are anonymous - context will not be stored in HttpSession. 2015-05-04 21:27:23.112 DEBUG 1260 --- [nio-8080-exec-7] s.s.w.c.SecurityContextPersistenceFilter : SecurityContextHolder now cleared, as request processing completed </code></pre> <p>Notable changes (And most likely the source of my issues):</p> <ul> <li>Credentials are read from MongoDB insteadOf yml file</li> <li>Project structure</li> </ul> <p>Since i wanted to use a database instead of property file, i added a user, userRepository, userDetailsService, and changed the security configuration a bit. Fronted code like Controllers (both from Spring MVC and Angular), .html &amp; .js files are not changed, so i don't think that the problem is in those, nevertheless i paste those lines also:</p> <p>PS: My test data is populated in db, can be read through JUnit tests with Spring Data like this (so i think that is also not the cause):</p> <pre><code>@Autowired private UserRepository userRepo; @Test public void testUserRepo() { User myUser = userRepo.findOneByUsername("myUser"); assertEquals("myPassword", myUser.getPassword()); Collection&lt;SimpleGrantedAuthority&gt; authorities = myUser.getAuthorities(); assertTrue(authorities.contains(new SimpleGrantedAuthority("ROLE_ADMIN"))); assertTrue(authorities.contains(new SimpleGrantedAuthority("ROLE_USER"))); } </code></pre> <p>Relevant Code:</p> <p><strong>User.java</strong></p> <pre><code>@Document(collection = "User") public class User implements UserDetails { /** * */ private static final long serialVersionUID = 7206798553934461899L; @Id private Long id; @NotNull @Size(min = 1, max = 20) private String username; @NotNull @Size(min = 4, max = 8) private String password; private Set&lt;SimpleGrantedAuthority&gt; authorities = new HashSet&lt;SimpleGrantedAuthority&gt;(); @Override public Collection&lt;SimpleGrantedAuthority&gt; getAuthorities() { return authorities; } </code></pre> <p><strong>UserRepository.java</strong></p> <pre><code>public interface UserRepository extends MongoRepository&lt;User, Long&gt; { User findOneByUsername(String username); } </code></pre> <p><strong>UserDetailsService.java</strong></p> <pre><code>@Service public class UserDetailsService implements org.springframework.security.core.userdetails.UserDetailsService { @Autowired private UserRepository repository; @Override public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { return repository.findOneByUsername(username); } } </code></pre> <p><strong>SecurityConfiguration.java</strong></p> <pre><code>@Configuration @Order(SecurityProperties.ACCESS_OVERRIDE_ORDER) public class SecurityConfiguration extends WebSecurityConfigurerAdapter { @Autowired private UserDetailsService userDetailsService; @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.userDetailsService(userDetailsService); } @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/index.html", "/home.html", "/login.html", "/").permitAll().anyRequest() .authenticated(); } } </code></pre> <p><strong>HomeController.java</strong></p> <pre><code>@RestController public class HomeController { @RequestMapping("/user") public Principal user(Principal user) { return user; } @RequestMapping("/resource") public Map&lt;String, Object&gt; home() { Map&lt;String, Object&gt; model = new HashMap&lt;String, Object&gt;(); Authentication auth = SecurityContextHolder.getContext().getAuthentication(); model.put("id", auth.getName()); model.put("content", "Hello World"); return model; } } </code></pre> <p><strong>Application.java</strong></p> <pre><code>@SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } </code></pre> <p><strong>login.html</strong></p> <pre><code>&lt;div class="alert alert-danger" ng-show="error"&gt; There was a problem logging in. Please try again. &lt;/div&gt; &lt;form role="form" ng-submit="login()"&gt; &lt;div class="form-group"&gt; &lt;label for="username"&gt;Username:&lt;/label&gt; &lt;input type="text" class="form-control" id="username" name="username" ng-model="credentials.username"/&gt; &lt;/div&gt; &lt;div class="form-group"&gt; &lt;label for="password"&gt;Password:&lt;/label&gt; &lt;input type="password" class="form-control" id="password" name="password" ng-model="credentials.password"/&gt; &lt;/div&gt; &lt;button type="submit" class="btn btn-primary"&gt;Submit&lt;/button&gt; &lt;/form&gt; </code></pre> <p><strong>hello.js</strong> (AngularJS Controller)</p> <pre><code>angular.module('hello', [ 'ngRoute' ]).config(function($routeProvider, $httpProvider) { $routeProvider.when('/', { templateUrl : 'home.html', controller : 'home' }).when('/login', { templateUrl : 'login.html', controller : 'navigation' }).otherwise('/'); $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; }).controller( 'navigation', function($rootScope, $scope, $http, $location, $route) { $scope.tab = function(route) { return $route.current &amp;&amp; route === $route.current.controller; }; var authenticate = function(credentials, callback) { var headers = credentials ? { authorization : "Basic " + btoa(credentials.username + ":" + credentials.password) } : {}; $http.get('user', { headers : headers }).success(function(data) { if (data.name) { $rootScope.authenticated = true; } else { $rootScope.authenticated = false; } callback &amp;&amp; callback($rootScope.authenticated); }).error(function() { $rootScope.authenticated = false; callback &amp;&amp; callback(false); }); } authenticate(); $scope.credentials = {}; $scope.login = function() { authenticate($scope.credentials, function(authenticated) { if (authenticated) { console.log("Login succeeded") $location.path("/"); $scope.error = false; $rootScope.authenticated = true; } else { console.log("Login failed") $location.path("/login"); $scope.error = true; $rootScope.authenticated = false; } }) }; $scope.logout = function() { $http.post('logout', {}).success(function() { $rootScope.authenticated = false; $location.path("/"); }).error(function(data) { console.log("Logout failed") $rootScope.authenticated = false; }); } }).controller('home', function($scope, $http) { $http.get('/resource/').success(function(data) { $scope.greeting = data; }) }); </code></pre>