В предыдущей статье мы впервые представили Spring Security и использовали базовую HTTP- аутентификацию по умолчанию для защиты ресурсов URL , а в этой статье мы используем аутентификацию формы для защиты ресурсов URL .
1. Аутентификация формы по умолчанию:
Сначала создайте новый пакет конфигурации для хранения общих конфигураций, затем создайте новый класс WebSecurityConfig для наследования WebSecurityConfigurerAdapter , как показано ниже:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
}
После добавления аннотации @EnableWebSecurity в класс WebSecurityConfig он будет автоматически обнаружен и зарегистрирован Spring (щелкните аннотацию @EnableWebSecurity , чтобы увидеть, что аннотация @Configuration уже существует, поэтому добавлять ее сюда не нужно).
Затем мы рассмотрим определение метода configure(HttpSecurity http) класса WebSecurityConfigurerAdapter . Следующее:
protected void configure(HttpSecurity http) throws Exception {
logger.debug("Using default configure(HttpSecurity). If subclassed this
will potentially override subclass configure(HttpSecurity).");
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().and()
.httpBasic();
}
Вы можете видеть, что WebSecurityConfigurerAdapter объявил некоторые функции безопасности по умолчанию:
А. Проверьте все запросы пользователей.
б) Разрешить пользователям аутентифицироваться с помощью формы входа в систему ( Spring Security предоставляет простую страницу входа в форму).
в) Разрешить пользователям использовать базовую аутентификацию HTTP .
Теперь перезапустите службу, чтобы применить новую конфигурацию безопасности. Как и ожидалось, при следующем посещении localhost:8080 нас попросят пройти аутентификацию с помощью формы. Как показано ниже:
На приведенном выше рисунке мы видим, что адрес, который мы посещаем, автоматически переходит на localhost:8080/login , что является страницей входа по умолчанию в Spring Security , Вам нужно только ввести правильное имя пользователя и пароль, чтобы вернуться к исходному доступу адрес .
2. Пользовательская аутентификация формы:
1. Предварительная настройка пользовательской формы страницы входа:
Хотя автоматически сгенерированная страница входа в форму может быть запущена удобно и быстро, большинство приложений предпочитают предоставлять свою собственную страницу входа в форму.В этом случае метод configure() необходимо переопределить следующим образом:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin().
loginPage("/myLogin.html")
// 使登录页不设限访问
.permitAll()
.and().
csrf().disable();
}
}
2. Знайте HttpSecurity:
HttpSecurity на самом деле соответствует тегам в xml- файле в методе конфигурации пространства имен Spring Security . Позволяет нам настраивать политики безопасности для определенных HTTP- запросов.
В xml- файле банально объявлять большое количество конфигураций, но в Java- конфигурации, по традиционному способу, нам нужно вызывать ее вот так, следующим образом:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
protected void configure(HttpSecurity http) throws Exception{
ExpressionUrlAuthorizationConfigurer.ExpressionInterceptUrlRegistry
urlRegistry=http.authorizeRequests();
ExpressionUrlAuthorizationConfigurer.AuthorizedUrl authorizedUrl =
(ExpressionUrlAuthorizationConfigurer.AuthorizedUrl)urlRegistry
.anyRequest();
authorizedUrl.authenticated();
// more
FormLoginConfigurer<HttpSecurity> formLoginConfigurer =
http.formLogin();
formLoginConfigurer.loginPage("/myLogin.html");
formLoginConfigurer.permitAll();
// more
}
}
Можете себе представить, насколько это хлопотно и болезненно. HttpSecurity сначала разработан как цепочка вызовов.После выполнения каждого метода будет возвращен ожидаемый контекст для облегчения непрерывных вызовов. Нам не нужно заботиться о деталях того, что возвращает каждый метод, как перейти к следующей конфигурации и так далее.
HttpSecurity предоставляет множество методов, связанных с настройкой, соответствующих вложенному тегу <http> в конфигурации пространства имен . Например, authorizeRequests() , formLogin() , httpBasic() и csrf() соответствуют тегам <intercept-url> , <form-login> , <http-basic> и <csrf> соответственно . После вызова этих методов контекст вернется к HttpSecurity , если для завершения текущего тега не используется метод and() , в противном случае контекст цепного вызова автоматически войдет в соответствующее поле тега .
Метод authorizeRequests() фактически возвращает регистр перехвата URL-адресов , мы можем вызывать методы anyRequest() , antMatchers() и regexMatchers() , предоставленные им, чтобы сопоставить URL-адрес системы и указать для него политику безопасности.
Методы formLogin() и httpBasic() объявляют методы аутентификации формы, предоставляемые Spring Security , и возвращают соответствующие конфигураторы соответственно. Среди них formLogin.loginPage("/myLogin.html") указывает пользовательскую страницу входа как /myLogin.html , и в то же время Spring Security зарегистрирует маршрут POST с /myLogin.html для получения запросов на вход.
Метод csrf() — это функция защиты от подделки межсайтовых запросов, предоставляемая Spring Security . Когда мы наследуем WebSecurityConfigurerAdapter , метод csrf () будет включен по умолчанию . Дополнительная информация о методе csrf() будет рассмотрена ниже. главы, чтобы упростить процесс тестирования.
После перезапуска службы посетите localhost:8080 здесь , и страница автоматически перейдет на localhost:8080/myLogin.html . Поскольку /myLogin.html не может найти ресурс страницы, будет отображаться страница 404 , как показано ниже:
3. Напишите страницу входа в форму:
Код страницы входа в форму myLogin.html выглядит следующим образом:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<div class = "login" style="width:300px;height:300px">
<h2>Acced Form</h2>
<div class ="login-top"></div>
<h1>LOGIN FORM</h1>
<form action="myLogin.html" method="post">
<input type="text" name="username" placeholder="username"/>
<input type="password" name="password" placeholder="password"/>
<div class="forgot" style="margin-top:20px;">
<a href="#">forgot Password</a>
<input type="submit" value="login">
</div>
</form>
<div class="login-bottom">
<h3>New User <a href ="">Register</a> </h3>
</div>
</div>
</body>
</html>
На странице входа в форму есть только одна форма, имя пользователя и пароль — это имя пользователя и пароль соответственно , и они отправляются в /myLogin.html в форме POST .
Мы помещаем этот файл в resources/static/ . Перезапустите службу, снова посетите localhost:8080 , и вы увидите страницу входа в настраиваемую форму, как показано ниже:
После ввода правильного имени пользователя и пароля нажмите кнопку входа для успешного перехода.
4. Другие элементы конфигурации формы:
После настройки страницы входа в форму URL-адрес для обработки запроса на вход изменится соответствующим образом Как настроить URL-адрес ? Очень просто, Spring Security предоставляет соответствующую поддержку в настройке формы, код выглядит следующим образом:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/myLogin.html")
.loginProcessingUrl("/login")
.permitAll()
.and()
.csrf().disable();
}
}
На этом этапе у некоторых читателей могут возникнуть сомнения, потому что по соглашению после отправки запроса на вход и успешной аутентификации страница вернется к исходной странице доступа. В некоторых системах происходит возврат к исходной странице доступа, но в некоторых системах, где передняя и задняя части полностью разделены и все взаимодействия выполняются только с помощью json , при входе в систему обычно возвращается часть данных json , чтобы информировать вне зависимости от того, был ли вход успешным или нет, решение о том, как обрабатывать последующую логику, принимает внешний интерфейс, а не сервер, активно выполняющий переходы между страницами. Это также возможно в Spring Security :
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter{
protected void configure(HttpSecurity http) throws Exception{
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.loginPage("/myLogin.html")
.loginProcessingUrl("/login")
.successHandler(new AuthenticationSuccessHandler() {
@Override
public void onAuthenticationSuccess(HttpServletRequest arg0,
HttpServletResponse arg1, Authentication arg2)
throws IOException, ServletException {
arg1.setContentType("application/json;charset=UTF-8");
PrintWriter out = arg1.getWriter();
out.write("{\"error_code\":\"0\",\"message\":\"欢迎登录系统\"}");
}
})
.failureHandler(new AuthenticationFailureHandler() {
@Override
public void onAuthenticationFailure(HttpServletRequest arg0,
HttpServletResponse arg1, AuthenticationException arg2)
throws IOException, ServletException {
arg1.setContentType("application/json;charset=UTF-8");
arg1.setStatus(401);
PrintWriter out = arg1.getWriter();
// 输出失败的原因
out.write("{\"error_code\":\"401\",\"name\":\""+arg2.getCause()+"\","
+ "\"message\":\""+arg2.getMessage()+"\"}}");
}
})
.and()
.csrf().disable();
}
}
Модуль конфигурации входа в форму предоставляет два метода, successHandler() и failureHandler() , которые обрабатывают логику успешного входа и неудачного входа соответственно. Среди них метод successHandler() имеет параметр Authentication , который содержит такую информацию, как текущее имя пользователя и его роль , а метод failureHandler() содержит параметр исключения AuthenticationException . Конкретный метод обработки должен быть настроен в соответствии с ситуацией в системе.
Формально мы используем функцию аутентификации формы Spring Security и настраиваем страницу входа в форму. Но на самом деле этого далеко не достаточно. Например, в реальной системе имя пользователя и пароль, которые мы используем для обычного входа в систему, берутся из базы данных, но здесь все они прописаны в конфигурации. Кроме того, мы можем установить подробные разрешения для каждого вошедшего в систему пользователя, а не общую роль. Это содержание будет объяснено в следующих главах.