Как выйти из oauth2 клиента весной?
У меня самый простой клиент oauth2:
@EnableAutoConfiguration
@Configuration
@EnableOAuth2Sso
@RestController
public class ClientApplication {
@RequestMapping("/")
public String home(Principal user, HttpServletRequest request, HttpServletResponse response) throws ServletException {
return "Hello " + user.getName();
}
public static void main(String[] args) {
new SpringApplicationBuilder(ClientApplication.class)
.properties("spring.config.name=application").run(args);
}
}
У меня также есть следующее application.yml
:
server:
port: 9999
servlet:
context-path: /client
security:
oauth2:
client:
client-id: acme
client-secret: acmesecret
access-token-uri: http://localhost:8080/oauth/token
user-authorization-uri: http://localhost:8080/oauth/authorize
resource:
user-info-uri: http://localhost:8080/me
logging:
level:
org.springframework.security: DEBUG
org.springframework.web: DEBUG
Это полный код. У меня нет дополнительного исходного кода. Он работает правильно.
Но теперь я хочу добавить функцию выхода из системы. Я добавил конечную точку, но она не работает. Я попытался сделать следующее:
@RequestMapping("/logout")
public void logout(HttpServletRequest request, HttpServletResponse response) throws ServletException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
authentication.setAuthenticated(false);
new SecurityContextLogoutHandler().logout(request,response,authentication);
SecurityContextHolder.clearContext();
request.logout();
request.getSession().invalidate();
}
Но я все еще зарегистрирован и могу получить доступ /
url, и он отвечает мне именем пользователя.
Можете ли вы помочь мне исправить эту проблему?
Обновить
Я пробовал описанный здесь подход https://spring.io/guides/tutorials/spring-boot-oauth2/#_social_login_logout:
@EnableAutoConfiguration
@Configuration
@EnableOAuth2Sso
@Controller
public class ClientApplication extends WebSecurityConfigurerAdapter {
private Logger logger = LoggerFactory.getLogger(ClientApplication.class);
@RequestMapping("/hello")
public String home(Principal user, HttpServletRequest request, HttpServletResponse response, Model model) throws ServletException {
model.addAttribute("name", user.getName());
return "hello";
}
@Override
protected void configure(HttpSecurity http) throws Exception {
// @formatter:off
http.antMatcher("/**")
.authorizeRequests()
.antMatchers( "/login**", "/webjars/**", "/error**").permitAll()
.anyRequest()
.authenticated()
.and().logout().logoutSuccessUrl("/").permitAll()
.and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
// @formatter:on
}
public static void main(String[] args) {
new SpringApplicationBuilder(ClientApplication.class)
.properties("spring.config.name=application").run(args);
}
}
и на FE я писал:
<script type="text/javascript">
$.ajaxSetup({
beforeSend: function (xhr, settings) {
if (settings.type == 'POST' || settings.type == 'PUT'
|| settings.type == 'DELETE') {
if (!(/^http:.*/.test(settings.url) || /^https:.*/
.test(settings.url))) {
// Only send the token to relative URLs i.e. locally.
xhr.setRequestHeader("X-XSRF-TOKEN",
Cookies.get('XSRF-TOKEN'));
}
}
}
});
var logout = function () {
$.post("/client/logout", function () {
$("#user").html('');
$(".unauthenticated").show();
$(".authenticated").hide();
});
return true;
};
$(function() {
$("#logoutButton").on("click", function () {
logout();
});
});
</script>
а также
<input type="button" id="logoutButton" value="Logout"/>
Но это все еще не работает. Это приводит к следующему поведению:
Сообщение http://localhost:9999/client/logout
перенаправляет на http://localhost:9999/client
но эта страница не существует
исходный код на gitub:
client - https://github.com/gredwhite/logour_social-auth-client (используйте localhost:9999/client/hello
url)
server - https://github.com/gredwhite/logout_social-auth-server
Ответы
Ответ 1
Вероятно, вы захотите использовать встроенную поддержку Spring Security для конечной точки/выхода из системы, которая пойдет правильно (очистить сеанс и аннулировать файл cookie). Чтобы настроить конечную точку, расширьте существующий метод configure() в нашем WebSecurityConfigurer:
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.and().logout().logoutSuccessUrl("/").permitAll();
}
Ответ 2
Добавьте следующий код в свой класс ClientApplication. Это также очистит ваши данные сеанса.
Замените ниже код на метод настройки вашего адаптера сети безопасности.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**")
.authorizeRequests()
.antMatchers( "/login**", "/webjars/**", "/error**").permitAll()
.anyRequest()
.authenticated()
.and().logout().invalidateHttpSession(true)
.clearAuthentication(true).logoutSuccessUrl("/login?logout").deleteCookies("JSESSIONID").permitAll().and().csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
}
Ответ 3
Попробуйте добавить URL-адрес выхода в конфигурацию безопасности.
.logout()
.logoutUrl("/logout")
.logoutSuccessUrl("/")
.permitAll();