我在使用AngularJS从Spring Boot https注销时遇到问题。在我刷新页面成功注销后(使用F5),我仍然在此窗口会话中获得第一个登录用户。
我正在使用基本认证,我的tomcat有两个端口:
8090 - http
8443 - https
8090用于重定向安全会话。
我尝试了很多解决方案,但迄今为止都没有。
这是我的配置:
的 application.properties
server.port=8443
server.ssl.key-store=****.p12
server.ssl.key-storepassword=*****
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=*****
SpringBoot主类
@SpringBootApplication
@EnableJpaRepositories
public class DanceSchoolManagementApplication {
@Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(initiateHttpConnector());
return tomcat;
}
private Connector initiateHttpConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
connector.setScheme("http");
connector.setPort(8090);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
public static void main(String[] args) {
SpringApplication.run(DanceSchoolManagementApplication.class, args);
}
}
SecurityConfiguration
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Autowired
private ManagementSecurityProperties managementSecurityProperties;
@Autowired
private UserDetailsService userDetailsService;
@Autowired
private LogoutSuccess logoutSuccess;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/index.html", "/")
.permitAll()
.anyRequest()
// .authenticated()
.fullyAuthenticated()
// .and()
// .logout()
// .logoutRequestMatcher(new AntPathRequestMatcher("/logout"))
// .logoutSuccessUrl("/")
// .logoutSuccessHandler(logoutSuccess)
// .deleteCookies("JSESSIONID")
// .invalidateHttpSession(true)
// .permitAll()
.and()
.addFilterAfter(new CsrfHeaderFilter(), CsrfFilter.class)
.csrf().csrfTokenRepository(csrfTokenRepository())
.and()
.sessionManagement()
.maximumSessions(1)
.maxSessionsPreventsLogin(true);
}
private CsrfTokenRepository csrfTokenRepository() {
HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
repository.setHeaderName("X-XSRF-TOKEN");
return repository;
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.authenticationProvider(createDaoAuthenticationProvider());
}
private DaoAuthenticationProvider createDaoAuthenticationProvider() {
DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(createBCryptPasswordEncoder());
return daoAuthenticationProvider;
}
@Bean
public PasswordEncoder createBCryptPasswordEncoder() {
return new BCryptPasswordEncoder(managementSecurityProperties.getBcryptStrength());
}
}
如您所见,我尝试了许多不同的配置选项,包括创建自己的LogoutSuccessHandlers,尝试删除cookie并使会话无效,但其中任何一个都适用于我。
以下是自定义注销休息方法:
@RequestMapping(method = RequestMethod.POST, value = "/auth/logout")
public boolean logout(HttpServletRequest request, HttpServletResponse response) {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if(auth != null) {
new SecurityContextLogoutHandler().logout(request,response,auth);
auth = null;
SecurityContextHolder.getContext().setAuthentication(auth);
SecurityContextHolder.setContext(SecurityContextHolder.createEmptyContext());
}
return true;
}
但是在刷新页面后我仍然能够获得经过身份验证的用户数据:
这是角度登录和注销:
验证服务
angular.module("danceSchoolManagement.authService",[])
.factory("authService", function ($http) {
var service = {};
service.authenticate = function(credentials, successFunction, failureFunction) {
var headers = credentials ? {
authorization: "Basic "
+ btoa(credentials.username + ":" + credentials.password)
} : {};
$http.get('/login/user', {headers: headers})
.success(successFunction)
.error(failureFunction);
};
service.logout = function(successFunction, failureFunction) {
$http.post('/auth/logout', {})
.success(successFunction)
.error(failureFunction);
};
return service;
});
登录控制器
angular.module("danceSchoolManagement.authController", [])
.controller("authController", function ($rootScope, $scope, authService) {
$scope.credentials = {};
$scope.authenticate = function (credentials) {
authService.authenticate(credentials,
function (returnedData) {
$rootScope.user = returnedData;
}, function (returnedData) {
$rootScope.user = null;
});
};
$scope.login = function () {
$scope.authenticate($scope.credentials);
};
$scope.authenticate();
$scope.logout = function () {
authService.logout(
function (returnedData) {
$rootScope.user = null;
}, function (returnedData) {
$rootScope.user = null;
});
};
});