#java #spring #spring-mvc #jakarta-ee #spring-security
#java #spring #spring-mvc #джакарта-ee #spring-безопасность
Вопрос:
Я хотел бы настроить Spring security 3.0.5 и изменить URL для входа в систему на /login вместо / j_spring_security_check.
Что мне нужно сделать, так это разрешить вход в каталог «/» и обеспечить «/admin/report.html страница».
Прежде всего, я создаю свой собственный фильтр, используя учебник и исходный код Spring Security:
public class MyFilter extends AbstractAuthenticationProcessingFilter {
private static final String DEFAULT_FILTER_PROCESSES_URL = "/login";
private static final String POST = "POST";
public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
protected MyFilter() {
super(DEFAULT_FILTER_PROCESSES_URL);
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response)
throws AuthenticationException, IOException, ServletException {
String username = obtainUsername(request);
String password = obtainPassword(request);
if (username == null) {
username = "";
}
if (password == null) {
password = "";
}
username = username.trim();
UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
HttpSession session = request.getSession(false);
if (session != null || getAllowSessionCreation()) {
request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
}
setDetails(request, authRequest);
return this.getAuthenticationManager().authenticate(authRequest);
}
protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) res;
if (request.getMethod().equals(POST)) {
// If the incoming request is a POST, then we send it up
// to the AbstractAuthenticationProcessingFilter.
super.doFilter(request, response, chain);
} else {
// If it's a GET, we ignore this request and send it
// to the next filter in the chain. In this case, that
// pretty much means the request will hit the /login
// controller which will process the request to show the
// login page.
chain.doFilter(request, response);
}
}
protected String obtainUsername(HttpServletRequest request) {
return request.getParameter(usernameParameter);
}
protected String obtainPassword(HttpServletRequest request) {
return request.getParameter(passwordParameter);
}
}
после этого я вношу следующие изменения в xml
<security:http auto-config="true">
<!--<session-management session-fixation-protection="none"/>-->
<security:custom-filter ref="myFilter" before="FORM_LOGIN_FILTER"/>
<security:intercept-url pattern="/admin/login.jsp*" filters="none"/>
<security:intercept-url pattern="/admin/report.html" access="ROLE_ADMIN"/>
<security:form-login login-page="/admin/login.jsp" login-processing-url="/login" always-use-default-target="true"/>
<security:logout logout-url="/logout" logout-success-url="/login.jsp" invalidate-session="true"/>
</security:http>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider>
<security:password-encoder hash="md5" />
<security:user-service>
<!-- peter/opal -->
<security:user name="peter" password="22b5c9accc6e1ba628cedc63a72d57f8" authorities="ROLE_ADMIN" />
</security:user-service>
</security:authentication-provider>
</security:authentication-manager>
<bean id="myFilter" class="com.vanilla.springMVC.controllers.MyFilter">
<property name="authenticationManager" ref="authenticationManager"/>
</bean>
и затем у меня есть JSP с моим кодом.
<form action="../login" method="post">
<label for="j_username">Username</label>
<input type="text" name="j_username" id="j_username" />
<br/>
<label for="j_password">Password</label>
<input type="password" name="j_password" id="j_password"/>
<br/>
<input type='checkbox' name='_spring_security_remember_me'/> Remember me on this computer.
<br/>
<input type="submit" value="Login"/>
</form>
при попытке перейти к /admin/report.html Я перенаправлен на страницу входа в систему.
но после отправки учетных данных я получаю:
HTTP Status 404 - /SpringMVC/login/
type Status report
message /SpringMVC/login/
description The requested resource (/SpringMVC/login/) is not available.
Похоже, у меня проблема в конфигурации, но я не могу понять, что является причиной этого.
Можете ли вы помочь?
Комментарии:
1.
action="../login"
?2. это правильно, ../login, потому что в противном случае я получу /admin /login, и мне нужна родительская папка.
3. Корень вашего приложения
/SpringMVC
?/SpringMVC/login/
правильно ли / должно ли быть доступно?4. Да, корневой каталог — это /SpringMVC /, затем защищенная папка /SpringMVC/admin/report.html а затем папка для входа /SpringMVC/admin/login.jsp.
5. Я полагаю, что моя проблема в xml-файле. но я могу разобраться, в чем проблема, у меня такое чувство, что мой фильтр не работает, но у меня есть подсказка, как это исправить.
Ответ №1:
Я опоздал с этим примерно на 12 месяцев, но для настройки URL-адреса входа в форму Spring Security для входа в систему вам не нужно создавать свой собственный фильтр. Один из атрибутов тега form-login позволяет задать пользовательский URL. На самом деле, вы также можете изменить имена полей j_username и j_password по умолчанию, используя атрибуты тега form-login. Вот пример:
<form-login login-page="/login" login-processing-url="/login.do" default-target-url="/" always-use-default-target="true" authentication-failure-url="/login?error=1" username-parameter="username" password-parameter="password"/>
Ответ №2:
Я думаю, что @Ischin правильно задается вопросом об URL-адресе действия формы. Попробуйте ввести полный путь и посмотрите, работает ли это. Если это произойдет, вы можете работать оттуда, чтобы выяснить, что не соответствует.
Единственное, что я могу придумать для проверки, — это отображение фильтра в вас web.xml . Поскольку вы заходите на страницу входа, у вас это настроено, но я бы проверил, что вы перехватываете не только URL-адреса с определенными расширениями и т.д.
Кроме того, к вашему сведению, если вы хотите, чтобы запрос (после того, как форма входа аутентифицирует пользователя) переходил к защищенному ресурсу (/admin/report.html в этом случае) тогда вам следует удалить форму:login always-use-default-target=»true». Установка этого флага в значение true приведет к тому, что запрос всегда будет переходить к целевому URL по умолчанию, который обычно не является тем, что вы хотите. Из документов spring security:
Сопоставляется свойству defaultTargetUrl фильтра UsernamePasswordAuthenticationFilter. Если не установлен, значение по умолчанию равно «/» (корень приложения). Пользователь будет перенаправлен на этот URL-адрес после входа в систему, при условии, что его не просили войти при попытке доступа к защищенному ресурсу, когда он будет перенаправлен на первоначально запрошенный URL.
Комментарии:
1. Пожалуйста, смотрите ответ ниже для получения дополнительной информации о понижающем голосовании